diff --git a/ui/core/app/router.js b/ui/core/app/router.js
index 95356d6c0..b0ef0cbf6 100644
--- a/ui/core/app/router.js
+++ b/ui/core/app/router.js
@@ -50,7 +50,9 @@ Router.map(function () {
this.route('project', { path: ':project_id' }, function() {
this.route('host-catalogs', function() {
this.route('new');
- this.route('host-catalog', { path: ':host_catalog_id' }, function() {});
+ this.route('host-catalog', { path: ':host_catalog_id' }, function() {
+ this.route('host-sets');
+ });
});
});
this.route('new');
diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets.js
new file mode 100644
index 000000000..c4440322e
--- /dev/null
+++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets.js
@@ -0,0 +1,13 @@
+import Route from '@ember/routing/route';
+
+export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsRoute extends Route {
+ /**
+ * Loads all host-sets under the current scope and host catalog.
+ * @return {Promise{[HostSetModel]}}
+ */
+ async model() {
+ const scopeID = this.modelFor('scopes.scope.projects.project').id;
+ const hostCatalogID = this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog').id;
+ return this.store.findAll('host-set', { adapterOptions: { scopeID, hostCatalogID } });
+ }
+}
diff --git a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog.hbs b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog.hbs
index d66e83390..0b7c956db 100644
--- a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog.hbs
+++ b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog.hbs
@@ -1,3 +1,38 @@
-{{title @model.displayName}}
+
-{{outlet}}
+
+
+
+
+
+ {{t "resources.host-catalog"}}
+
+
+
+
+
+ {{t 'actions.delete-host-catalog'}}
+
+
+
+
+
+
+
+ {{t 'titles.details'}}
+
+
+ {{t 'titles.host-sets'}}
+
+
+
+
+
+ {{outlet}}
+
+
+
diff --git a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets.hbs b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets.hbs
new file mode 100644
index 000000000..300abe57b
--- /dev/null
+++ b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets.hbs
@@ -0,0 +1,25 @@
+
+
+
+ {{t "form.label.name"}}
+ {{t "form.label.type"}}
+ {{t "form.label.id"}}
+
+
+
+ {{#each @model as |hostSet|}}
+
+
+ {{hostSet.displayName}}
+ {{hostSet.description}}
+
+
+ {{hostSet.type}}
+
+
+ {{hostSet.id}}
+
+
+ {{/each}}
+
+
\ No newline at end of file
diff --git a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/index.hbs
index 6d7c05659..71bdd4437 100644
--- a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/index.hbs
+++ b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/index.hbs
@@ -1,39 +1,5 @@
-
-
-
-
-
-
-
- {{t "resources.host-catalog"}}
-
-
-
-
-
- {{t 'titles.details'}}
-
-
-
-
-
-
-
- {{t 'actions.delete-host-catalog'}}
-
-
-
-
-
-
-
-
-
+
diff --git a/ui/core/tests/acceptance/host-sets-test.js b/ui/core/tests/acceptance/host-sets-test.js
new file mode 100644
index 000000000..4f398902f
--- /dev/null
+++ b/ui/core/tests/acceptance/host-sets-test.js
@@ -0,0 +1,78 @@
+import { module, test } from 'qunit';
+import { visit, currentURL } from '@ember/test-helpers';
+import { setupApplicationTest } from 'ember-qunit';
+import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
+import a11yAudit from 'ember-a11y-testing/test-support/audit';
+import {
+ authenticateSession,
+ // These are left here intentionally for future reference.
+ //currentSession,
+ //invalidateSession,
+} from 'ember-simple-auth/test-support';
+
+module('Acceptance | host sets', function (hooks) {
+ setupApplicationTest(hooks);
+ setupMirage(hooks);
+
+ const instances = {
+ scopes: {
+ global: null,
+ org: null,
+ project: null,
+ hostCatalog: null
+ },
+ hostSet: null
+ };
+ const urls = {
+ orgScope: null,
+ projects: null,
+ project: null,
+ hostCatalogs: null,
+ hostCatalog: null,
+ hostSets: null
+ };
+
+ hooks.beforeEach(function () {
+ // Setup Mirage mock resources for this test
+ instances.scopes.global = this.server.create('scope', { id: 'global' });
+ instances.scopes.org = this.server.create('scope', { type: 'org',
+ scope: { id: instances.scopes.global.id, type: instances.scopes.global.type }
+ });
+ instances.scopes.project = this.server.create('scope', { type: 'project',
+ scope: { id: instances.scopes.org.id, type: instances.scopes.org.type }
+ });
+ instances.scopes.hostCatalog = this.server.create('host-catalog', {
+ scope: {
+ id: instances.scopes.project.id,
+ type: instances.scopes.project.type
+ }
+ });
+
+ instances.hostSet = this.server.create('host-set', {
+ scope: {
+ id: instances.scopes.project.id,
+ type: instances.scopes.project.type
+ },
+ hostCatalog: {
+ id: instances.scopes.hostCatalog.id,
+ type: instances.scopes.hostCatalog.type
+ }
+ });
+
+ // Generate route URLs for resources
+ urls.orgScope = `/scopes/${instances.scopes.org.id}`;
+ urls.projects = `${urls.orgScope}/projects`;
+ urls.project = `${urls.projects}/${instances.scopes.hostCatalog.scope.id}`;
+ urls.hostCatalogs = `${urls.project}/host-catalogs`;
+ urls.hostCatalog = `${urls.hostCatalogs}/${instances.scopes.hostCatalog.id}`;
+ urls.hostSets = `${urls.hostCatalog}/host-sets`;
+ });
+
+ test('visiting host sets', async function (assert) {
+ assert.expect(1);
+ authenticateSession();
+ await visit(urls.hostSets);
+ await a11yAudit();
+ assert.equal(currentURL(), urls.hostSets);
+ });
+});
diff --git a/ui/core/tests/unit/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets-test.js b/ui/core/tests/unit/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets-test.js
new file mode 100644
index 000000000..9cdd5b757
--- /dev/null
+++ b/ui/core/tests/unit/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets-test.js
@@ -0,0 +1,11 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'ember-qunit';
+
+module('Unit | Route | scopes/scope/projects/project/host-catalogs/host-catalog/host-sets', function(hooks) {
+ setupTest(hooks);
+
+ test('it exists', function(assert) {
+ let route = this.owner.lookup('route:scopes/scope/projects/project/host-catalogs/host-catalog/host-sets');
+ assert.ok(route);
+ });
+});
diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml
index cd73f8bbb..31e60a02d 100644
--- a/ui/core/translations/en-us.yaml
+++ b/ui/core/translations/en-us.yaml
@@ -40,6 +40,7 @@ resources:
host-catalogs: Host Catalogs
auth-method: Auth Method
auth-methods: Auth Methods
+ host-sets: Host Sets
titles:
iam: IAM
new: New
@@ -58,6 +59,7 @@ titles:
grants: Permissions
new-grant: New Grant
principals: Principals
+ host-sets: Host Sets
global: Global
descriptions:
host-catalogs: Overview of collections of hosts and host sets.