diff --git a/changelog/26325.txt b/changelog/26325.txt new file mode 100644 index 000000000000..cbfc6c1f9c64 --- /dev/null +++ b/changelog/26325.txt @@ -0,0 +1,3 @@ +```release-note:bug +ui: fixed a bug where the replication pages did not update display when navigating between DR and performance +``` diff --git a/ui/lib/replication/addon/components/replication-summary.js b/ui/lib/replication/addon/components/replication-summary.js index 0812b99a3434..5a862e465e3d 100644 --- a/ui/lib/replication/addon/components/replication-summary.js +++ b/ui/lib/replication/addon/components/replication-summary.js @@ -3,8 +3,7 @@ * SPDX-License-Identifier: BUSL-1.1 */ -import { inject as service } from '@ember/service'; -import { alias } from '@ember/object/computed'; +import { service } from '@ember/service'; import { computed } from '@ember/object'; import Component from '@ember/component'; import decodeConfigFromJWT from 'replication/utils/decode-config-from-jwt'; @@ -27,6 +26,7 @@ export default Component.extend(ReplicationActions, DEFAULTS, { replicationMode: 'dr', mode: 'primary', version: service(), + rm: service('replication-mode'), didReceiveAttrs() { this._super(...arguments); const initialReplicationMode = this.initialReplicationMode; @@ -38,7 +38,9 @@ export default Component.extend(ReplicationActions, DEFAULTS, { initialReplicationMode: null, cluster: null, - replicationAttrs: alias('cluster.replicationAttrs'), + attrsForCurrentMode: computed('cluster', 'rm.mode', function () { + return this.cluster[this.rm.mode]; + }), tokenIncludesAPIAddr: computed('token', function () { const config = decodeConfigFromJWT(this.token); diff --git a/ui/lib/replication/addon/templates/components/replication-summary.hbs b/ui/lib/replication/addon/templates/components/replication-summary.hbs index c32a365a53e6..b42ed5dd5859 100644 --- a/ui/lib/replication/addon/templates/components/replication-summary.hbs +++ b/ui/lib/replication/addon/templates/components/replication-summary.hbs @@ -336,7 +336,7 @@ {{/if}} {{/if}} {{else}} - {{#if (eq this.replicationAttrs.mode "initializing")}} + {{#if (eq this.attrsForCurrentMode.mode "initializing")}} The cluster is initializing replication. This may take some time. {{else}}

{{this.cluster.replicationModeStatus.cluster_id}}

@@ -345,28 +345,28 @@ - {{#if (eq this.replicationAttrs.mode "secondary")}} + {{#if (eq this.attrsForCurrentMode.mode "secondary")}} {{else}} - + {{/if}} diff --git a/ui/mirage/handlers/index.js b/ui/mirage/handlers/index.js index b736c6a8af5e..17c094e64b9f 100644 --- a/ui/mirage/handlers/index.js +++ b/ui/mirage/handlers/index.js @@ -16,6 +16,7 @@ import oidcConfig from './oidc-config'; import hcpLink from './hcp-link'; import kubernetes from './kubernetes'; import ldap from './ldap'; +import replication from './replication'; export { base, @@ -29,4 +30,5 @@ export { mfaConfig, mfaLogin, oidcConfig, + replication, }; diff --git a/ui/mirage/handlers/replication.js b/ui/mirage/handlers/replication.js new file mode 100644 index 000000000000..4a1d2ff6c52a --- /dev/null +++ b/ui/mirage/handlers/replication.js @@ -0,0 +1,107 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +export default function (server) { + server.get('sys/replication/status', function () { + return { + data: { + dr: { + cluster_id: 'dr-cluster-id', + corrupted_merkle_tree: false, + known_secondaries: ['foobar'], + last_corruption_check_epoch: '-62135596800', + last_dr_wal: 98, + last_reindex_epoch: '0', + last_wal: 98, + merkle_root: 'ad721f32ed6789a1e5824841f358a517340a4585', + mode: 'primary', + primary_cluster_addr: 'dr-foobar', + secondaries: [ + { + api_address: 'http://127.0.0.1:8202', + cluster_address: 'https://127.0.0.1:8203', + connection_status: 'disconnected', + last_heartbeat: '2024-04-09T09:04:22-05:00', + node_id: 'foobar', + }, + ], + ssct_generation_counter: 0, + state: 'running', + }, + performance: { + cluster_id: 'perf-cluster-id', + corrupted_merkle_tree: false, + known_secondaries: [], + last_corruption_check_epoch: '-62135596800', + last_performance_wal: 98, + last_reindex_epoch: '0', + last_wal: 98, + merkle_root: '618c9136bb443aa584f5d6b90755d42888c9c54a', + mode: 'primary', + primary_cluster_addr: 'perf-foobar', + secondaries: [], + ssct_generation_counter: 0, + state: 'running', + }, + }, + }; + }); + + server.get('sys/replication/performance/status', function () { + return { + data: { + cluster_id: 'perf-cluster-id', + corrupted_merkle_tree: false, + known_secondaries: ['foobar'], + last_corruption_check_epoch: '-62135596800', + last_dr_wal: 98, + last_reindex_epoch: '0', + last_wal: 98, + merkle_root: 'ad721f32ed6789a1e5824841f358a517340a4585', + mode: 'primary', + primary_cluster_addr: 'perf-foobar', + secondaries: [ + { + api_address: 'http://127.0.0.1:8202', + cluster_address: 'https://127.0.0.1:8203', + connection_status: 'disconnected', + last_heartbeat: '2024-04-09T09:04:22-05:00', + node_id: 'foobar', + }, + ], + ssct_generation_counter: 0, + state: 'running', + }, + }; + }); + + server.get('sys/replication/dr/status', function () { + return { + data: { + cluster_id: 'dr-cluster-id', + corrupted_merkle_tree: false, + known_secondaries: ['foobar'], + last_corruption_check_epoch: '-62135596800', + last_dr_wal: 98, + last_reindex_epoch: '0', + last_wal: 98, + merkle_root: 'ad721f32ed6789a1e5824841f358a517340a4585', + mode: 'primary', + primary_cluster_addr: 'dr-foobar', + secondaries: [ + { + api_address: 'http://127.0.0.1:8202', + cluster_address: 'https://127.0.0.1:8203', + connection_status: 'disconnected', + last_heartbeat: '2024-04-09T09:04:22-05:00', + node_id: 'foobar', + }, + ], + ssct_generation_counter: 0, + state: 'running', + }, + }; + }); +} diff --git a/ui/tests/acceptance/replication-nav-test.js b/ui/tests/acceptance/replication-nav-test.js new file mode 100644 index 000000000000..5edd37230a71 --- /dev/null +++ b/ui/tests/acceptance/replication-nav-test.js @@ -0,0 +1,55 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; +import { setupMirage } from 'ember-cli-mirage/test-support'; +import authPage from 'vault/tests/pages/auth'; +import ENV from 'vault/config/environment'; +import { click } from '@ember/test-helpers'; + +const SELECTORS = { + navReplication: '[data-test-sidebar-nav-link="Replication"]', + navPerformance: '[data-test-sidebar-nav-link="Performance"]', + navDR: '[data-test-sidebar-nav-link="Disaster Recovery"]', + title: '[data-test-replication-title]', + primaryCluster: '[data-test-value-div="primary_cluster_addr"]', + replicationSet: '[data-test-row-value="Replication set"]', + knownSecondariesTitle: '.known-secondaries-card h3', +}; +module('Acceptance | Enterprise | replication navigation', function (hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + hooks.before(function () { + ENV['ember-cli-mirage'].handler = 'replication'; + }); + hooks.after(function () { + ENV['ember-cli-mirage'].handler = null; + }); + + hooks.beforeEach(function () { + return authPage.login(); + }); + + test('navigate between replication types updates page', async function (assert) { + await click(SELECTORS.navReplication); + assert.dom(SELECTORS.title).hasText('Disaster Recovery & Performance primary'); + await click(SELECTORS.navPerformance); + + // Ensure data is expected for performance + assert.dom(SELECTORS.title).hasText('Performance primary'); + assert.dom(SELECTORS.primaryCluster).hasText('perf-foobar'); + assert.dom(SELECTORS.replicationSet).hasText('perf-cluster-id'); + assert.dom(SELECTORS.knownSecondariesTitle).hasText('0 Known secondaries'); + + // Nav to DR and see updated data + await click(SELECTORS.navDR); + assert.dom(SELECTORS.title).hasText('Disaster Recovery primary'); + assert.dom(SELECTORS.primaryCluster).hasText('dr-foobar'); + assert.dom(SELECTORS.replicationSet).hasText('dr-cluster-id'); + assert.dom(SELECTORS.knownSecondariesTitle).hasText('1 Known secondaries'); + }); +});