mirror of
https://github.com/hashicorp/vault.git
synced 2026-05-05 12:26:34 +02:00
UI: reorg replication (#28332)
* Add replication-overview-mode component + tests * Move both primary view higher to template * simplify replication-summary component * remove replication-mode-summary * Add jsdocs to replication-overview-mode * fix overview-mode test * fix page/mode-index test * copyright * address PR comments * note to devs
This commit is contained in:
parent
abdeda43ca
commit
e1c56a300f
@ -1,16 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
.replication-description {
|
||||
flex-shrink: 1;
|
||||
|
||||
.title {
|
||||
margin-bottom: $spacing-8;
|
||||
}
|
||||
|
||||
.detail-tags {
|
||||
margin-bottom: $spacing-16;
|
||||
}
|
||||
}
|
||||
@ -91,7 +91,6 @@
|
||||
@import './components/read-more';
|
||||
@import './components/regex-validator';
|
||||
@import './components/replication-dashboard';
|
||||
@import './components/replication-mode-summary';
|
||||
@import './components/replication-page';
|
||||
@import './components/replication-summary';
|
||||
@import './components/role-item';
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { service } from '@ember/service';
|
||||
import { equal } from '@ember/object/computed';
|
||||
import { get, computed } from '@ember/object';
|
||||
import Component from '@ember/component';
|
||||
import layout from '../templates/components/replication-mode-summary';
|
||||
|
||||
const replicationAttr = function (attr) {
|
||||
return computed(`cluster.{dr,performance}.${attr}`, 'cluster', 'mode', function () {
|
||||
const { mode, cluster } = this;
|
||||
return get(cluster, `${mode}.${attr}`);
|
||||
});
|
||||
};
|
||||
export default Component.extend({
|
||||
layout,
|
||||
version: service(),
|
||||
router: service(),
|
||||
namespace: service(),
|
||||
classNameBindings: ['isMenu::box'],
|
||||
attributeBindings: ['href', 'target'],
|
||||
display: 'banner',
|
||||
isMenu: equal('display', 'menu'),
|
||||
href: computed(
|
||||
'cluster.id',
|
||||
'display',
|
||||
'mode',
|
||||
'replicationEnabled',
|
||||
'version.hasPerfReplication',
|
||||
function () {
|
||||
const display = this.display;
|
||||
const mode = this.mode;
|
||||
if (mode === 'performance' && display === 'menu' && this.version.hasPerfReplication === false) {
|
||||
return 'https://www.hashicorp.com/products/vault';
|
||||
}
|
||||
if (this.replicationEnabled || display === 'menu') {
|
||||
return this.router.urlFor('vault.cluster.replication.mode.index', this.cluster.id, mode);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
),
|
||||
target: computed('isPerformance', 'version.hasPerfReplication', function () {
|
||||
if (this.isPerformance && this.version.hasPerfReplication === false) {
|
||||
return '_blank';
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
internalLink: false,
|
||||
isPerformance: equal('mode', 'performance'),
|
||||
replicationEnabled: replicationAttr('replicationEnabled'),
|
||||
replicationUnsupported: equal('cluster.mode', 'unsupported'),
|
||||
replicationDisabled: replicationAttr('replicationDisabled'),
|
||||
syncProgressPercent: replicationAttr('syncProgressPercent'),
|
||||
syncProgress: replicationAttr('syncProgress'),
|
||||
secondaryId: replicationAttr('secondaryId'),
|
||||
modeForUrl: replicationAttr('modeForUrl'),
|
||||
clusterIdDisplay: replicationAttr('clusterIdDisplay'),
|
||||
mode: null,
|
||||
cluster: null,
|
||||
modeState: computed('cluster', 'mode', function () {
|
||||
const { cluster, mode } = this;
|
||||
const clusterState = cluster[mode].state;
|
||||
return clusterState;
|
||||
}),
|
||||
});
|
||||
@ -1,122 +0,0 @@
|
||||
{{!
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
~}}
|
||||
|
||||
{{#if this.isMenu}}
|
||||
{{! this is the status menu }}
|
||||
<div class="level is-mobile">
|
||||
<div class="is-flex-grow-1">
|
||||
{{#if this.replicationUnsupported}}
|
||||
Unsupported
|
||||
{{else if this.replicationEnabled}}
|
||||
<div>
|
||||
{{concat (if (eq this.mode "performance") "Performance " "Disaster Recovery ") (capitalize this.modeForUrl)}}
|
||||
</div>
|
||||
{{#if this.secondaryId}}
|
||||
<small>
|
||||
<code>
|
||||
{{this.secondaryId}}
|
||||
</code>
|
||||
</small>
|
||||
{{/if}}
|
||||
<small>
|
||||
<code>
|
||||
{{this.clusterIdDisplay}}
|
||||
</code>
|
||||
</small>
|
||||
{{else if (and (eq this.mode "performance") (not (has-feature "Performance Replication")))}}
|
||||
Learn more
|
||||
{{else if this.auth.currentToken}}
|
||||
Enable
|
||||
{{if (eq this.mode "performance") "Performance" "Disaster Recovery"}}
|
||||
{{else}}
|
||||
<span class="has-text-grey-light">
|
||||
{{if (eq this.mode "performance") "Performance" "Disaster Recovery"}}
|
||||
</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="level-right">
|
||||
{{#if this.replicationEnabled}}
|
||||
{{#if (cluster-states this.modeState)}}
|
||||
<span class={{if (get (cluster-states this.modeState) "isOk") "has-text-success" "has-text-danger"}}>
|
||||
<Icon @name={{get (cluster-states this.modeState) "glyph"}} />
|
||||
</span>
|
||||
{{else if this.syncProgress}}
|
||||
<progress value={{this.syncProgressPercent}} max="100" class="progress is-small is-narrow is-info">
|
||||
{{this.syncProgress.progress}}
|
||||
of
|
||||
{{this.syncProgress.total}}
|
||||
keys
|
||||
</progress>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<Icon @name="minus-circle" aria-label="Replication not enabled" class="has-text-grey-light" />
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
{{! this is the replication index page }}
|
||||
<div class="level">
|
||||
<div class="replication-description level-left">
|
||||
<div>
|
||||
{{#if (and (eq this.mode "performance") (not (has-feature "Performance Replication")))}}
|
||||
<p>
|
||||
Performance Replication is a feature of Vault Enterprise Premium.
|
||||
<ExternalLink
|
||||
@href="https://hashicorp.com/products/vault/trial?source=vaultui_Performance%20Replication"
|
||||
class="link"
|
||||
data-test-upgrade-link-performance
|
||||
>
|
||||
Upgrade
|
||||
</ExternalLink>
|
||||
</p>
|
||||
{{else if (and (eq this.mode "dr") (not (has-feature "DR Replication")))}}
|
||||
<p>
|
||||
Disaster Recovery is a feature of Vault Enterprise Premium.
|
||||
<ExternalLink
|
||||
@href="https://hashicorp.com/products/vault/trial?source=vaultui_Performance%20Replication"
|
||||
class="link"
|
||||
data-test-upgrade-link-dr
|
||||
>
|
||||
Upgrade
|
||||
</ExternalLink>
|
||||
</p>
|
||||
{{else if this.replicationEnabled}}
|
||||
<h6 class="title is-6 is-uppercase">
|
||||
Enabled
|
||||
</h6>
|
||||
<div class="detail-tags">
|
||||
<span class="has-text-grey">
|
||||
{{capitalize this.modeForUrl}}
|
||||
</span>
|
||||
{{#if this.secondaryId}}
|
||||
<span class="tag is-light has-text-grey-dark">
|
||||
<code>
|
||||
{{this.secondaryId}}
|
||||
</code>
|
||||
</span>
|
||||
{{/if}}
|
||||
<span class="tag is-light has-text-grey-dark">
|
||||
<code>
|
||||
{{this.clusterIdDisplay}}
|
||||
</code>
|
||||
</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
<p class="help has-text-grey-dark">
|
||||
{{replication-mode-description this.mode}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="level-right">
|
||||
<Hds::Button
|
||||
@route="mode.index"
|
||||
@models={{array this.cluster.name this.mode}}
|
||||
@color={{if this.replicationDisabled "primary" "secondary"}}
|
||||
@text={{if this.replicationDisabled "Enable" "Details"}}
|
||||
data-test-replication-details-link={{this.mode}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
@ -1,6 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
export { default } from 'core/components/replication-mode-summary';
|
||||
@ -0,0 +1,49 @@
|
||||
{{!
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
~}}
|
||||
|
||||
<Hds::Card::Container @level="mid" @hasBorder={{true}} ...attributes>
|
||||
<div class="has-padding-m">
|
||||
<div class="flex">
|
||||
<Icon @size="24" @name={{this.details.icon}} />
|
||||
<Hds::Text::Display
|
||||
@tag="h2"
|
||||
@size="400"
|
||||
data-test-overview-mode-title
|
||||
>{{this.details.blockTitle}}</Hds::Text::Display>
|
||||
</div>
|
||||
<div class="has-top-padding-m has-bottom-padding-m" data-test-overview-mode-body>
|
||||
{{#if (not (has-feature this.details.feature))}}
|
||||
<Hds::Text::Body @size="300" @tag="div">
|
||||
{{this.details.upgradeTitle}}
|
||||
<Hds::Link::Inline @href={{this.details.upgradeLink}} data-test-upgrade-link={{@mode}}>
|
||||
Upgrade
|
||||
</Hds::Link::Inline>
|
||||
</Hds::Text::Body>
|
||||
{{else if @model.replicationEnabled}}
|
||||
<Hds::Text::Body @tag="div" @size="300" @weight="semibold" @color="strong">ENABLED</Hds::Text::Body>
|
||||
<div class="has-bottom-padding-s">
|
||||
<Hds::Text::Body @color="faint">{{capitalize @model.modeForUrl}}</Hds::Text::Body>
|
||||
{{#if @model.secondaryId}}
|
||||
<Hds::Badge @text={{@model.secondaryId}} />
|
||||
{{/if}}
|
||||
{{#if @model.clusterIdDisplay}}
|
||||
<Hds::Badge @text={{@model.clusterIdDisplay}} />
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<Hds::Text::Body @color="faint">{{replication-mode-description @mode}}</Hds::Text::Body>
|
||||
</div>
|
||||
{{#if (has-feature this.details.feature)}}
|
||||
<Hds::Button
|
||||
@route="mode.index"
|
||||
@models={{array @clusterName @mode}}
|
||||
@color={{if @model.replicationEnabled "secondary" "primary"}}
|
||||
@text={{if @model.replicationEnabled "Details" "Enable"}}
|
||||
data-test-replication-details-link={{@mode}}
|
||||
/>
|
||||
{{/if}}
|
||||
</div>
|
||||
</Hds::Card::Container>
|
||||
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import Component from '@glimmer/component';
|
||||
|
||||
/**
|
||||
* @module ReplicationOverviewModeComponent
|
||||
* ReplicationOverviewMode components are used on the Replication index page to display
|
||||
* details about a given mode (DR or Performance) status.
|
||||
*
|
||||
* @example
|
||||
* <ReplicationOverviewModeComponent @mode="dr" @model={{this.cluster.dr}} @clusterName={{this.cluster.name}} />
|
||||
*
|
||||
* @param {string} mode - should be "dr" or "performance"
|
||||
* @param {ReplicationAttributesModel} model - either the dr or performance attribute of the cluster model
|
||||
* @param {string} clusterName - used for the link to the mode details
|
||||
*/
|
||||
export default class ReplicationOverviewModeComponent extends Component {
|
||||
get details() {
|
||||
if (this.args.mode === 'dr') {
|
||||
return {
|
||||
blockTitle: 'Disaster Recovery (DR)',
|
||||
upgradeTitle: 'Disaster Recovery is a feature of Vault Enterprise Premium.',
|
||||
upgradeLink: 'https://hashicorp.com/products/vault/trial?source=vaultui_DR%20Replication',
|
||||
feature: 'DR Replication',
|
||||
icon: 'replication-direct',
|
||||
};
|
||||
}
|
||||
return {
|
||||
blockTitle: 'Performance',
|
||||
upgradeTitle: 'Performance Replication is a feature of Vault Enterprise Premium.',
|
||||
upgradeLink: 'https://hashicorp.com/products/vault/trial?source=vaultui_Performance%20Replication',
|
||||
feature: 'Performance Replication',
|
||||
icon: 'replication-perf',
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,13 @@ import { computed } from '@ember/object';
|
||||
import Component from '@ember/component';
|
||||
import ReplicationActions from 'core/mixins/replication-actions';
|
||||
|
||||
/**
|
||||
* @module ReplicationSummary
|
||||
* ReplicationSummary component is a component to show the mode-specific summary for replication
|
||||
*
|
||||
* @param {ClusterModel} cluster - the cluster ember-data model
|
||||
* @param {string} initialReplicationMode - mode for replication details we want to see, either "dr" or "performance"
|
||||
*/
|
||||
export default Component.extend(ReplicationActions, {
|
||||
'data-test-replication-summary': true,
|
||||
attributeBindings: ['data-test-replication-summary'],
|
||||
@ -22,7 +29,6 @@ export default Component.extend(ReplicationActions, {
|
||||
this.set('replicationMode', initialReplicationMode);
|
||||
}
|
||||
},
|
||||
showModeSummary: false,
|
||||
initialReplicationMode: null,
|
||||
cluster: null,
|
||||
|
||||
|
||||
@ -3,88 +3,39 @@
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
~}}
|
||||
|
||||
{{#if (not (has-feature "DR Replication"))}}
|
||||
<UpgradePage @title="Replication" />
|
||||
{{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" data-test-replication-title>
|
||||
Replication
|
||||
</h1>
|
||||
</p.levelLeft>
|
||||
</PageHeader>
|
||||
{{/if}}
|
||||
|
||||
{{#if (and (eq this.cluster.dr.mode "primary") (eq this.cluster.performance.mode "primary"))}}
|
||||
{{#if (eq this.attrsForCurrentMode.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.header @showTabs={{true}} />
|
||||
<Page.dashboard @componentToRender="replication-summary-card" as |Dashboard|>
|
||||
<Dashboard.card @title="Disaster Recovery" />
|
||||
<Dashboard.card @title="Performance" />
|
||||
<Page.dashboard
|
||||
@data={{this.cluster}}
|
||||
@componentToRender={{if
|
||||
(eq this.attrsForCurrentMode.mode "secondary")
|
||||
"replication-secondary-card"
|
||||
"replication-primary-card"
|
||||
}}
|
||||
as |Dashboard|
|
||||
>
|
||||
{{#if (eq this.attrsForCurrentMode.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.attrsForCurrentMode.state) "glyph"}}
|
||||
@metric={{this.attrsForCurrentMode.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.attrsForCurrentMode.lastWAL}}
|
||||
/>
|
||||
<Dashboard.secondaryCard @cluster={{this.cluster}} @replicationAttrs={{this.attrsForCurrentMode}} />
|
||||
{{/if}}
|
||||
</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}}
|
||||
<ReplicationModeSummary @mode="dr" @cluster={{this.cluster}} @tagName="span" />
|
||||
{{/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>
|
||||
<ReplicationModeSummary @mode="performance" @cluster={{this.cluster}} @tagName="span" />
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{else}}
|
||||
{{#if (eq this.attrsForCurrentMode.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.attrsForCurrentMode.mode "secondary")
|
||||
"replication-secondary-card"
|
||||
"replication-primary-card"
|
||||
}}
|
||||
as |Dashboard|
|
||||
>
|
||||
{{#if (eq this.attrsForCurrentMode.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.attrsForCurrentMode.state) "glyph"}}
|
||||
@metric={{this.attrsForCurrentMode.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.attrsForCurrentMode.lastWAL}}
|
||||
/>
|
||||
<Dashboard.secondaryCard @cluster={{this.cluster}} @replicationAttrs={{this.attrsForCurrentMode}} />
|
||||
{{/if}}
|
||||
</Page.dashboard>
|
||||
</ReplicationPage>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
@ -6,6 +6,7 @@
|
||||
<section class="section">
|
||||
<div class="container is-widescreen">
|
||||
{{#if (eq this.model.mode "unsupported")}}
|
||||
{{! Replication is unsupported in non-enterprise or when using non-transactional storage (eg inmem) }}
|
||||
<PageHeader as |p|>
|
||||
<p.levelLeft>
|
||||
<h1 class="title is-3 has-text-grey" data-test-replication-title>
|
||||
@ -98,8 +99,36 @@
|
||||
@onSuccess={{this.onEnableSuccess}}
|
||||
@doTransition={{true}}
|
||||
/>
|
||||
{{else if (not (has-feature "DR Replication"))}}
|
||||
<UpgradePage @title="Replication" />
|
||||
{{else if (and (eq this.model.dr.mode "primary") (eq this.model.performance.mode "primary"))}}
|
||||
{{! Renders when cluster is primary for both replication modes }}
|
||||
<ReplicationPage @model={{this.model}} 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}}
|
||||
<ReplicationSummary @cluster={{this.model}} @showModeSummary={{true}} @onDisable={{this.onDisable}} />
|
||||
{{! Renders when at least one mode is not enabled }}
|
||||
<PageHeader as |p|>
|
||||
<p.levelLeft>
|
||||
<h1 class="title is-3" data-test-replication-title>
|
||||
Replication
|
||||
</h1>
|
||||
</p.levelLeft>
|
||||
</PageHeader>
|
||||
|
||||
<div class="box is-sideless is-fullwidth is-marginless flex-col">
|
||||
<ReplicationOverviewMode
|
||||
@mode="dr"
|
||||
@model={{this.model.dr}}
|
||||
@clusterName={{this.model.name}}
|
||||
class="has-bottom-margin-m"
|
||||
/>
|
||||
<ReplicationOverviewMode @mode="performance" @model={{this.model.performance}} @clusterName={{this.model.name}} />
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</section>
|
||||
@ -22,7 +22,7 @@ module('Integration | Component | replication page/mode-index', function (hooks)
|
||||
hooks.beforeEach(function () {
|
||||
this.store = this.owner.lookup('service:store');
|
||||
this.onEnable = () => {};
|
||||
this.clusterModel = {};
|
||||
this.clusterModel = { replicationAttrs: {} };
|
||||
this.replicationMode = '';
|
||||
this.replicationDisabled = true;
|
||||
|
||||
|
||||
@ -0,0 +1,124 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'vault/tests/helpers';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { setupEngine } from 'ember-engines/test-support';
|
||||
|
||||
const OVERVIEW_MODE = {
|
||||
title: '[data-test-overview-mode-title]',
|
||||
body: '[data-test-overview-mode-body]',
|
||||
detailsLink: '[data-test-replication-details-link]',
|
||||
};
|
||||
module('Integration | Component | replication-overview-mode', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
setupEngine(hooks, 'replication');
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.versionService = this.owner.lookup('service:version');
|
||||
this.versionService.features = [];
|
||||
this.mode = 'dr';
|
||||
this.clusterName = 'foobar';
|
||||
this.modeDetails = { mode: 'disabled' };
|
||||
|
||||
this.renderComponent = async () => {
|
||||
return render(
|
||||
hbs`
|
||||
<ReplicationOverviewMode
|
||||
@clusterName={{this.clusterName}}
|
||||
@mode={{this.mode}}
|
||||
@model={{this.modeDetails}}
|
||||
/>`,
|
||||
{ owner: this.engine }
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
test('without features', async function (assert) {
|
||||
await this.renderComponent();
|
||||
assert.dom(OVERVIEW_MODE.title).hasText('Disaster Recovery (DR)');
|
||||
assert
|
||||
.dom(OVERVIEW_MODE.body)
|
||||
.includesText('Disaster Recovery is a feature of Vault Enterprise Premium. Upgrade');
|
||||
assert.dom(OVERVIEW_MODE.detailsLink).doesNotExist('does not show link to replication (dr)');
|
||||
|
||||
this.set('mode', 'performance');
|
||||
await settled();
|
||||
assert.dom(OVERVIEW_MODE.title).hasText('Performance');
|
||||
assert
|
||||
.dom(OVERVIEW_MODE.body)
|
||||
.includesText('Performance Replication is a feature of Vault Enterprise Premium. Upgrade');
|
||||
assert.dom(OVERVIEW_MODE.detailsLink).doesNotExist('does not show link to replication (perf)');
|
||||
});
|
||||
|
||||
module('with features', function (hooks) {
|
||||
hooks.beforeEach(function () {
|
||||
this.versionService.features = ['DR Replication', 'Performance Replication'];
|
||||
});
|
||||
|
||||
test('it renders when replication disabled', async function (assert) {
|
||||
await this.renderComponent();
|
||||
assert.dom(OVERVIEW_MODE.title).hasText('Disaster Recovery (DR)');
|
||||
assert
|
||||
.dom(OVERVIEW_MODE.body)
|
||||
.hasText(
|
||||
'Disaster Recovery Replication is designed to protect against catastrophic failure of entire clusters. Secondaries do not forward service requests until they are elected and become a new primary.'
|
||||
);
|
||||
assert.dom(OVERVIEW_MODE.detailsLink).hasText('Enable');
|
||||
|
||||
this.set('mode', 'performance');
|
||||
await settled();
|
||||
assert.dom(OVERVIEW_MODE.title).hasText('Performance');
|
||||
assert
|
||||
.dom(OVERVIEW_MODE.body)
|
||||
.hasText(
|
||||
'Performance Replication scales workloads horizontally across clusters to make requests faster. Local secondaries handle read requests but forward writes to the primary to be handled.'
|
||||
);
|
||||
assert.dom(OVERVIEW_MODE.detailsLink).hasText('Enable');
|
||||
});
|
||||
|
||||
test('it renders when replication enabled', async function (assert) {
|
||||
this.mode = 'performance';
|
||||
this.modeDetails = {
|
||||
replicationEnabled: true,
|
||||
mode: 'primary',
|
||||
modeForUrl: 'primary',
|
||||
clusterIdDisplay: 'foobar12',
|
||||
};
|
||||
await this.renderComponent();
|
||||
assert.dom(OVERVIEW_MODE.title).hasText('Performance');
|
||||
assert
|
||||
.dom(OVERVIEW_MODE.body)
|
||||
.includesText('ENABLED Primary foobar12', 'renders mode type and cluster ID if passed');
|
||||
assert.dom(OVERVIEW_MODE.detailsLink).hasText('Details');
|
||||
|
||||
this.set('modeDetails', {
|
||||
replicationEnabled: true,
|
||||
mode: 'secondary',
|
||||
modeForUrl: 'secondary',
|
||||
clusterIdDisplay: 'foobar12',
|
||||
secondaryId: 'some-secondary',
|
||||
});
|
||||
await settled();
|
||||
assert.dom(OVERVIEW_MODE.title).hasText('Performance');
|
||||
assert.dom(OVERVIEW_MODE.body).includesText('ENABLED Secondary some-secondary foobar12');
|
||||
assert.dom(OVERVIEW_MODE.detailsLink).hasText('Details');
|
||||
});
|
||||
|
||||
test('it renders when replication bootstrapping', async function (assert) {
|
||||
this.modeDetails = {
|
||||
replicationEnabled: true,
|
||||
mode: 'bootstrapping',
|
||||
modeForUrl: 'bootstrapping',
|
||||
};
|
||||
await this.renderComponent();
|
||||
assert.dom(OVERVIEW_MODE.title).hasText('Disaster Recovery (DR)');
|
||||
assert.dom(OVERVIEW_MODE.body).includesText('ENABLED Bootstrapping');
|
||||
assert.dom(OVERVIEW_MODE.detailsLink).hasText('Details');
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user