diff --git a/.changelog/10835.txt b/.changelog/10835.txt
new file mode 100644
index 000000000..26d026b1e
--- /dev/null
+++ b/.changelog/10835.txt
@@ -0,0 +1,3 @@
+```release-note:feature
+ui: Create Routing Configurations route and page
+```
\ No newline at end of file
diff --git a/ui/packages/consul-ui/app/components/consul/source/README.mdx b/ui/packages/consul-ui/app/components/consul/source/README.mdx
new file mode 100644
index 000000000..970bfc3f8
--- /dev/null
+++ b/ui/packages/consul-ui/app/components/consul/source/README.mdx
@@ -0,0 +1,20 @@
+# Consul::Source
+
+A presentational component for showing a source name. This is a similar component to `Consul::Kind` and `Consul::ExternalSource`, except `Consul::Source` does not relate to a Service.
+
+```hbs preview-template
+
+```
+
+### Arguments
+
+| Argument/Attribute | Type | Default | Description |
+| --- | --- | --- | --- |
+| `source` | `string` | | A string to be passed down and displayed as the source name. |
+
+### See
+
+- [Template Source Code](./index.hbs)
+- [Styling Source Code](./index.scss)
+
+---
diff --git a/ui/packages/consul-ui/app/components/consul/source/index.hbs b/ui/packages/consul-ui/app/components/consul/source/index.hbs
new file mode 100644
index 000000000..3e237b5c5
--- /dev/null
+++ b/ui/packages/consul-ui/app/components/consul/source/index.hbs
@@ -0,0 +1,25 @@
+
+ -
+
+ {{@source}}
+
+
+ -
+
+
+ {{t "components.consul.source.header"}}
+
+
+
-
+ {{t "components.consul.source.menu-title"}}
+
+ -
+
+ {{t "components.consul.source.links.documentation"}}
+
+
+
+
+
+
+
diff --git a/ui/packages/consul-ui/app/components/consul/source/index.scss b/ui/packages/consul-ui/app/components/consul/source/index.scss
new file mode 100644
index 000000000..1ae170ae6
--- /dev/null
+++ b/ui/packages/consul-ui/app/components/consul/source/index.scss
@@ -0,0 +1,3 @@
+.consul-source {
+ @extend %pill-200, %frame-gray-600, %p1;
+}
diff --git a/ui/packages/consul-ui/app/router.js b/ui/packages/consul-ui/app/router.js
index 3f7af1d03..6fe466e7b 100644
--- a/ui/packages/consul-ui/app/router.js
+++ b/ui/packages/consul-ui/app/router.js
@@ -205,6 +205,9 @@ export const routes = {
},
},
},
+ 'routing-config': {
+ _options: { path: '/routing-config/:name' },
+ },
},
// Shows a datacenter picker. If you only have one
// it just redirects you through.
diff --git a/ui/packages/consul-ui/app/routes/dc/routing-config.js b/ui/packages/consul-ui/app/routes/dc/routing-config.js
new file mode 100644
index 000000000..d8203c662
--- /dev/null
+++ b/ui/packages/consul-ui/app/routes/dc/routing-config.js
@@ -0,0 +1,19 @@
+import Route from 'consul-ui/routing/route';
+import { inject as service } from '@ember/service';
+
+export default class RoutingConfigRoute extends Route {
+ @service('data-source/service') data;
+
+ async model(params) {
+ const dc = this.modelFor('dc').dc.Name;
+ const nspace = this.optionalParams().nspace;
+ const name = params.name;
+
+ return {
+ dc: dc,
+ nspace: nspace,
+ slug: name,
+ chain: await this.data.source(uri => uri`/${nspace}/${dc}/discovery-chain/${params.name}`),
+ };
+ }
+}
diff --git a/ui/packages/consul-ui/app/styles/components.scss b/ui/packages/consul-ui/app/styles/components.scss
index 3493ff5bc..d3f0608c9 100644
--- a/ui/packages/consul-ui/app/styles/components.scss
+++ b/ui/packages/consul-ui/app/styles/components.scss
@@ -80,6 +80,7 @@
@import 'consul-ui/components/consul/exposed-path/list';
@import 'consul-ui/components/consul/external-source';
@import 'consul-ui/components/consul/kind';
+@import 'consul-ui/components/consul/source';
@import 'consul-ui/components/consul/intention';
@import 'consul-ui/components/consul/lock-session/list';
@import 'consul-ui/components/consul/lock-session/form';
diff --git a/ui/packages/consul-ui/app/styles/layout.scss b/ui/packages/consul-ui/app/styles/layout.scss
index 04a9146df..31942ed8c 100644
--- a/ui/packages/consul-ui/app/styles/layout.scss
+++ b/ui/packages/consul-ui/app/styles/layout.scss
@@ -49,7 +49,8 @@ html[data-route$='edit'] .app-view > header + div > *:first-child {
/* needs a top margun :S */
%app-view-content .tab-section > *:first-child:not(.filter-bar):not(table),
%app-view-content .tab-section > .search-bar + p,
-%app-view-content .tab-section .consul-health-check-list {
+%app-view-content .tab-section .consul-health-check-list,
+%app-view-content .container {
margin-top: 1.25em;
}
.consul-upstream-instance-list,
diff --git a/ui/packages/consul-ui/app/templates/dc/routing-config.hbs b/ui/packages/consul-ui/app/templates/dc/routing-config.hbs
new file mode 100644
index 000000000..5a147723c
--- /dev/null
+++ b/ui/packages/consul-ui/app/templates/dc/routing-config.hbs
@@ -0,0 +1,22 @@
+{{page-title @model.slug}}
+
+
+
+
+ - All Services
+
+
+
+
+ {{@model.slug}}
+
+
+
+
+
+
+
+
+
diff --git a/ui/packages/consul-ui/tests/acceptance/dc/routing-config.feature b/ui/packages/consul-ui/tests/acceptance/dc/routing-config.feature
new file mode 100644
index 000000000..095314d6f
--- /dev/null
+++ b/ui/packages/consul-ui/tests/acceptance/dc/routing-config.feature
@@ -0,0 +1,21 @@
+@setupApplicationTest
+Feature: dc / routing-config
+ Scenario: Viewing a routing config
+ Given 1 datacenter model with the value "dc1"
+ When I visit the routingConfig page for yaml
+ ---
+ dc: dc1
+ name: virtual-1
+ ---
+ Then the url should be /dc1/routing-config/virtual-1
+ Then I don't see status on the error like "404"
+ And the title should be "virtual-1 - Consul"
+ Scenario: Viewing a source pill
+ Given 1 datacenter model with the value "dc1"
+ When I visit the routingConfig page for yaml
+ ---
+ dc: dc1
+ name: virtual-1
+ ---
+ And I see source
+
diff --git a/ui/packages/consul-ui/tests/acceptance/steps/dc/routing-config-steps.js b/ui/packages/consul-ui/tests/acceptance/steps/dc/routing-config-steps.js
new file mode 100644
index 000000000..3c9a76f69
--- /dev/null
+++ b/ui/packages/consul-ui/tests/acceptance/steps/dc/routing-config-steps.js
@@ -0,0 +1,10 @@
+import steps from '../steps';
+
+// step definitions that are shared between features should be moved to the
+// tests/acceptance/steps/steps.js file
+
+export default function(assert) {
+ return steps(assert).then('I should find a file', function() {
+ assert.ok(true, this.step);
+ });
+}
diff --git a/ui/packages/consul-ui/tests/pages.js b/ui/packages/consul-ui/tests/pages.js
index 264b1efe7..e2b9600d6 100644
--- a/ui/packages/consul-ui/tests/pages.js
+++ b/ui/packages/consul-ui/tests/pages.js
@@ -52,6 +52,7 @@ import consulKvListFactory from 'consul-ui/components/consul/kv/list/pageobject'
import index from 'consul-ui/tests/pages/index';
import dcs from 'consul-ui/tests/pages/dc';
import settings from 'consul-ui/tests/pages/settings';
+import routingConfig from 'consul-ui/tests/pages/dc/routing-config';
import services from 'consul-ui/tests/pages/dc/services/index';
import service from 'consul-ui/tests/pages/dc/services/show';
import instance from 'consul-ui/tests/pages/dc/services/instance';
@@ -230,4 +231,5 @@ export default {
nspace(visitable, submitable, deletable, cancelable, policySelector, roleSelector)
),
settings: create(settings(visitable, submitable, isPresent)),
+ routingConfig: create(routingConfig(visitable, text)),
};
diff --git a/ui/packages/consul-ui/tests/pages/dc/routing-config.js b/ui/packages/consul-ui/tests/pages/dc/routing-config.js
new file mode 100644
index 000000000..232659026
--- /dev/null
+++ b/ui/packages/consul-ui/tests/pages/dc/routing-config.js
@@ -0,0 +1,8 @@
+import { text } from 'ember-cli-page-object';
+
+export default function(visitable, isPresent) {
+ return {
+ visit: visitable('/:dc/routing-config/:name'),
+ source: text('[data-test-consul-source]'),
+ };
+}
diff --git a/ui/packages/consul-ui/tests/unit/routes/dc/routing-config-test.js b/ui/packages/consul-ui/tests/unit/routes/dc/routing-config-test.js
new file mode 100644
index 000000000..a15db71b1
--- /dev/null
+++ b/ui/packages/consul-ui/tests/unit/routes/dc/routing-config-test.js
@@ -0,0 +1,11 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'ember-qunit';
+
+module('Unit | Route | dc/routing-config', function(hooks) {
+ setupTest(hooks);
+
+ test('it exists', function(assert) {
+ let route = this.owner.lookup('route:dc/routing-config');
+ assert.ok(route);
+ });
+});
diff --git a/ui/packages/consul-ui/translations/components/consul/en-us.yaml b/ui/packages/consul-ui/translations/components/consul/en-us.yaml
index a603d989a..a036277e0 100644
--- a/ui/packages/consul-ui/translations/components/consul/en-us.yaml
+++ b/ui/packages/consul-ui/translations/components/consul/en-us.yaml
@@ -152,3 +152,9 @@ topology-metrics:
header: No traffic
body: Add "{upstream}" as an explicit upstream of "{downstream}" or set the "{downstream}" proxy to "transparent" mode to enable traffic.
action: Documentation
+source:
+ header: This is not a registered Consul service. It’s a routing configuration that routes traffic to real services in Consul. For more information, read our documentation.
+ menu-title: About Routing Configs
+ links:
+ documentation: Documentation
+
diff --git a/ui/packages/consul-ui/translations/routes/en-us.yaml b/ui/packages/consul-ui/translations/routes/en-us.yaml
index ad62451f3..47462dc2a 100644
--- a/ui/packages/consul-ui/translations/routes/en-us.yaml
+++ b/ui/packages/consul-ui/translations/routes/en-us.yaml
@@ -42,3 +42,5 @@ dc:
header: Transparent proxy mode
body: The upstreams listed on this page have been defined in a proxy registration. There may be more upstreams, though, as "transparent" mode is enabled on this proxy.
footer: Read the documentation
+ routing-config:
+ source: Routing Configuration