diff --git a/.changelog/20359.txt b/.changelog/20359.txt
new file mode 100644
index 0000000000..c010b32ef5
--- /dev/null
+++ b/.changelog/20359.txt
@@ -0,0 +1,3 @@
+```release-note:feature
+ui: Adds a redirect and warning message around unavailable UI with V2 enabled
+```
diff --git a/ui/packages/consul-ui/app/routes/application.js b/ui/packages/consul-ui/app/routes/application.js
index 40dce71533..8cc6ce87e2 100644
--- a/ui/packages/consul-ui/app/routes/application.js
+++ b/ui/packages/consul-ui/app/routes/application.js
@@ -13,13 +13,21 @@ export default class ApplicationRoute extends Route.extend(WithBlockingActions)
@service('client/http') client;
@service('env') env;
@service() hcp;
+ @service() router;
data;
+ beforeModel() {
+ if (this.env.var('CONSUL_V2_CATALOG_ENABLED')) {
+ this.router.replaceWith('unavailable');
+ }
+ }
+
async model() {
if (this.env.var('CONSUL_ACLS_ENABLED')) {
await this.hcp.updateTokenIfNecessary(this.env.var('CONSUL_HTTP_TOKEN'));
}
+
return {};
}
diff --git a/ui/packages/consul-ui/app/routes/unavailable.js b/ui/packages/consul-ui/app/routes/unavailable.js
new file mode 100644
index 0000000000..8bee82ffb2
--- /dev/null
+++ b/ui/packages/consul-ui/app/routes/unavailable.js
@@ -0,0 +1,18 @@
+/**
+ * Copyright (c) HashiCorp, Inc.
+ * SPDX-License-Identifier: BUSL-1.1
+ */
+
+import Route from 'consul-ui/routing/route';
+import { inject as service } from '@ember/service';
+
+export default class UnavailableRoute extends Route {
+ @service('env') env;
+ @service() router;
+
+ beforeModel() {
+ if (!this.env.var('CONSUL_V2_CATALOG_ENABLED')) {
+ this.router.replaceWith('index');
+ }
+ }
+}
diff --git a/ui/packages/consul-ui/app/templates/application.hbs b/ui/packages/consul-ui/app/templates/application.hbs
index bab98e7b1f..b0c9054ce6 100644
--- a/ui/packages/consul-ui/app/templates/application.hbs
+++ b/ui/packages/consul-ui/app/templates/application.hbs
@@ -7,41 +7,46 @@
{{! Add the a11y route announcer }}
- {{! Tell CSS what we have enabled }}
- {{#if (can 'use acls')}}
- {{document-attrs class="has-acls"}}
- {{/if}}
- {{#if (can 'use nspaces')}}
- {{document-attrs class="has-nspaces" }}
- {{/if}}
- {{#if (can 'use partitions')}}
- {{document-attrs class="has-partitions" }}
- {{/if}}
- {{! Listen out for blocking query/client setting changes }}
-
+ {{#unless (env 'CONSUL_V2_CATALOG_ENABLED')}}
+ {{! Tell CSS what we have enabled }}
+ {{#if (can 'use acls')}}
+ {{document-attrs class='has-acls'}}
+ {{/if}}
+ {{#if (can 'use nspaces')}}
+ {{document-attrs class='has-nspaces'}}
+ {{/if}}
+ {{#if (can 'use partitions')}}
+ {{document-attrs class='has-partitions'}}
+ {{/if}}
- {{! Tell CSS about our theme }}
-
- {{#each-in source.data as |key value|}}
- {{#if (and value (includes key (array 'color-scheme' 'contrast')))}}
- {{document-attrs class=(concat "prefers-" key "-" value) }}
- {{/if}}
- {{/each-in}}
-
-
- {{! If ACLs are enabled try get a token }}
- {{#if (can 'use acls')}}
+ {{! Listen out for blocking query/client setting changes }}
- {{/if}}
- {{#if (not-eq route.currentName 'oauth-provider-debug')}}
+ {{! Tell CSS about our theme }}
+
+ {{#each-in source.data as |key value|}}
+ {{#if (and value (includes key (array 'color-scheme' 'contrast')))}}
+ {{document-attrs class=(concat 'prefers-' key '-' value)}}
+ {{/if}}
+ {{/each-in}}
+
+
+ {{! If ACLs are enabled try get a token }}
+ {{#if (can 'use acls')}}
+
+ {{/if}}
+ {{/unless}}
+
+ {{#if
+ (and (not (env 'CONSUL_V2_CATALOG_ENABLED')) (not-eq route.currentName 'oauth-provider-debug'))
+ }}
{{! redirect if we aren't on a URL with dc information }}
{{#if (eq route.currentName 'index')}}
@@ -140,4 +145,4 @@
{{outlet}}
{{/if}}
-
+
\ No newline at end of file
diff --git a/ui/packages/consul-ui/app/templates/unavailable.hbs b/ui/packages/consul-ui/app/templates/unavailable.hbs
new file mode 100644
index 0000000000..8c591f8238
--- /dev/null
+++ b/ui/packages/consul-ui/app/templates/unavailable.hbs
@@ -0,0 +1,106 @@
+{{!
+ Copyright (c) HashiCorp, Inc.
+ SPDX-License-Identifier: BUSL-1.1
+}}
+
+
+ {{#if (env 'CONSUL_V2_CATALOG_ENABLED')}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{/if}}
+
\ No newline at end of file
diff --git a/ui/packages/consul-ui/tests/acceptance/unavailable-test.js b/ui/packages/consul-ui/tests/acceptance/unavailable-test.js
new file mode 100644
index 0000000000..9a983dc994
--- /dev/null
+++ b/ui/packages/consul-ui/tests/acceptance/unavailable-test.js
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) HashiCorp, Inc.
+ * SPDX-License-Identifier: BUSL-1.1
+ */
+
+import { module, test } from 'qunit';
+import { currentURL, visit } from '@ember/test-helpers';
+import { setupApplicationTest } from 'ember-qunit';
+import { setupTestEnv } from 'consul-ui/services/env';
+
+const unavailableHeaderSelector = '[data-test-unavailable-header]';
+const unavailableBodySelector = '[data-test-unavailable-body]';
+
+module('Acceptance | unavailable page', function (hooks) {
+ setupApplicationTest(hooks);
+
+ test('it redirects to the unavailable page when the v2 catalog is enabled', async function (assert) {
+ assert.expect(3);
+
+ setupTestEnv(this.owner, {
+ CONSUL_V2_CATALOG_ENABLED: true,
+ });
+
+ await visit('/');
+ assert.equal(currentURL(), '/unavailable', 'It should redirect to the unavailable page');
+
+ // Expect the warning message to be visible
+ assert.dom(unavailableHeaderSelector).hasText('User Interface Unavailable');
+ assert.dom(unavailableBodySelector).exists({ count: 1 });
+ });
+
+ test('it does not redirect to the unavailable page', async function (assert) {
+ assert.expect(3);
+
+ setupTestEnv(this.owner, {
+ CONSUL_V2_CATALOG_ENABLED: false,
+ });
+
+ await visit('/');
+ assert.equal(
+ currentURL(),
+ '/dc1/services',
+ 'It should continue to the services page when v2 catalog is disabled'
+ );
+
+ // Expect the warning message to be not be visible
+ assert.dom(unavailableHeaderSelector).doesNotExist();
+ assert.dom(unavailableBodySelector).doesNotExist();
+ });
+
+ test('it redirects away from the unavailable page when v2 catalog is not enabled', async function (assert) {
+ assert.expect(3);
+
+ setupTestEnv(this.owner, {
+ CONSUL_V2_CATALOG_ENABLED: false,
+ });
+
+ await visit('/unavailable');
+ assert.equal(currentURL(), '/dc1/services', 'It should redirect to the services page');
+
+ // Expect the warning message to be not be visible
+ assert.dom(unavailableHeaderSelector).doesNotExist();
+ assert.dom(unavailableBodySelector).doesNotExist();
+ });
+});
diff --git a/ui/packages/consul-ui/vendor/consul-ui/routes.js b/ui/packages/consul-ui/vendor/consul-ui/routes.js
index 07abd5c1b7..214b8fc8b8 100644
--- a/ui/packages/consul-ui/vendor/consul-ui/routes.js
+++ b/ui/packages/consul-ui/vendor/consul-ui/routes.js
@@ -439,6 +439,9 @@
redirect: '../settings',
},
},
+ unavailable: {
+ _options: { path: '/unavailable' },
+ },
notfound: {
_options: { path: '/*notfound' },
},