From 3eb205a87d80bfd78606ac76cacf232dcaa5ebc4 Mon Sep 17 00:00:00 2001 From: Chelsea Shaw <82459713+hashishaw@users.noreply.github.com> Date: Thu, 2 Nov 2023 12:55:09 -0500 Subject: [PATCH] UI: chroot namespace listener (#23942) --- changelog/23942.txt | 3 ++ ui/app/adapters/cluster.js | 5 +++ ui/app/models/cluster.js | 2 + ui/app/models/node.js | 7 ++- ui/app/routes/vault/cluster/dashboard.js | 16 ++++--- ui/app/services/version.js | 2 +- ui/app/templates/error.hbs | 46 ++++++++++++++++++++ ui/app/templates/vault/cluster/dashboard.hbs | 12 ++--- ui/mirage/handlers/chroot-namespace.js | 15 +++++++ ui/mirage/handlers/index.js | 2 + ui/package.json | 1 + ui/tests/acceptance/chroot-namespace-test.js | 29 ++++++++++++ ui/tests/acceptance/dashboard-test.js | 9 ++-- 13 files changed, 127 insertions(+), 22 deletions(-) create mode 100644 changelog/23942.txt create mode 100644 ui/app/templates/error.hbs create mode 100644 ui/mirage/handlers/chroot-namespace.js create mode 100644 ui/tests/acceptance/chroot-namespace-test.js diff --git a/changelog/23942.txt b/changelog/23942.txt new file mode 100644 index 0000000000..a4d43d48f0 --- /dev/null +++ b/changelog/23942.txt @@ -0,0 +1,3 @@ +```release-note:bug +ui: fix broken GUI when accessing from listener with chroot_namespace defined +``` diff --git a/ui/app/adapters/cluster.js b/ui/app/adapters/cluster.js index de173feb88..7469e062cd 100644 --- a/ui/app/adapters/cluster.js +++ b/ui/app/adapters/cluster.js @@ -80,6 +80,11 @@ export default ApplicationAdapter.extend({ performancestandbycode: 200, }, unauthenticated: true, + }).catch(() => { + // sys/health will only fail when chroot set + // because it's allowed in root namespace only and + // configured to return a 200 response in other fail scenarios + return { has_chroot_namespace: true }; }); }, diff --git a/ui/app/models/cluster.js b/ui/app/models/cluster.js index 543ed7bf0a..6ac7f90af3 100644 --- a/ui/app/models/cluster.js +++ b/ui/app/models/cluster.js @@ -16,6 +16,8 @@ export default class ClusterModel extends Model { @attr('boolean') standby; @attr('string') type; @attr('object') license; + // manually set on response when sys/health failure + @attr('boolean') hasChrootNamespace; /* Licensing concerns */ get licenseExpiry() { diff --git a/ui/app/models/node.js b/ui/app/models/node.js index 520368c72d..003d3f7ab9 100644 --- a/ui/app/models/node.js +++ b/ui/app/models/node.js @@ -9,17 +9,16 @@ import { alias, and, equal } from '@ember/object/computed'; export default Model.extend({ name: attr('string'), // https://developer.hashicorp.com/vault/api-docs/system/health - initialized: attr('boolean'), - sealed: attr('boolean'), - isSealed: alias('sealed'), standby: attr('boolean'), isActive: equal('standby', false), - clusterName: attr('string'), clusterId: attr('string'), isLeader: and('initialized', 'isActive'), // https://developer.hashicorp.com/vault/api-docs/system/seal-status + initialized: attr('boolean'), + sealed: attr('boolean'), + isSealed: alias('sealed'), // The "t" parameter is the threshold, and "n" is the number of shares. t: attr('number'), n: attr('number'), diff --git a/ui/app/routes/vault/cluster/dashboard.js b/ui/app/routes/vault/cluster/dashboard.js index b50a68c1db..37b2cb88b7 100644 --- a/ui/app/routes/vault/cluster/dashboard.js +++ b/ui/app/routes/vault/cluster/dashboard.js @@ -29,18 +29,20 @@ export default class VaultClusterDashboardRoute extends Route.extend(ClusterRout model() { const clusterModel = this.modelFor('vault.cluster'); - const replication = { - dr: clusterModel.dr, - performance: clusterModel.performance, - }; - + const hasChroot = clusterModel?.hasChrootNamespace; + const replication = hasChroot + ? null + : { + dr: clusterModel.dr, + performance: clusterModel.performance, + }; return hash({ replication, secretsEngines: this.store.query('secret-engine', {}), license: this.store.queryRecord('license', {}).catch(() => null), - isRootNamespace: this.namespace.inRootNamespace, + isRootNamespace: this.namespace.inRootNamespace && !hasChroot, version: this.version, - vaultConfiguration: this.getVaultConfiguration(), + vaultConfiguration: hasChroot ? null : this.getVaultConfiguration(), }); } diff --git a/ui/app/services/version.js b/ui/app/services/version.js index fe1ec0aae8..cf99b759c7 100644 --- a/ui/app/services/version.js +++ b/ui/app/services/version.js @@ -44,7 +44,7 @@ export default class VersionService extends Service { @task *getVersion() { if (this.version) return; - const response = yield this.store.adapterFor('cluster').health(); + const response = yield this.store.adapterFor('cluster').sealStatus(); this.version = response.version; return; } diff --git a/ui/app/templates/error.hbs b/ui/app/templates/error.hbs new file mode 100644 index 0000000000..9448637df4 --- /dev/null +++ b/ui/app/templates/error.hbs @@ -0,0 +1,46 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: BUSL-1.1 +~}} + +
Error {{this.model.httpStatus}}
++ {{this.model.message}} + {{join ". " this.model.errors}} +
+ +