diff --git a/ui/core/app/components/form/host/index.hbs b/ui/core/app/components/form/host/index.hbs
new file mode 100644
index 000000000..9152b0ba0
--- /dev/null
+++ b/ui/core/app/components/form/host/index.hbs
@@ -0,0 +1,55 @@
+
+
+
+
+
+ {{#if @model.errors.name}}
+
+ {{#each @model.errors.name as |error|}}
+ {{error.message}}
+ {{/each}}
+
+ {{/if}}
+
+
+
+ {{#if @model.errors.description}}
+
+ {{#each @model.errors.description as |error|}}
+ {{error.message}}
+ {{/each}}
+
+ {{/if}}
+
+
+
+
+
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
index b77bfcf35..74f1a2783 100644
--- 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
@@ -15,9 +15,7 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsRo
* @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 } });
+ return this.store.findAll('host-set', this.adapterOptions());
}
// =actions
diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/new.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/new.js
index 87f67abc7..f0dbcc3bd 100644
--- a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/new.js
+++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/new.js
@@ -6,7 +6,7 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsNe
/**
* Creates a new unsaved host set in current host catalog scope.
- * @return {HostCatalogModel}
+ * @return {HostSetModel}
*/
model() {
const scopeModel = this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog');
diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts.js
index 0799bc36b..805112d67 100644
--- a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts.js
+++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts.js
@@ -1,4 +1,81 @@
import Route from '@ember/routing/route';
+import { inject as service } from '@ember/service';
+import { action } from '@ember/object';
export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsRoute extends Route {
+ // =services
+
+ @service intl;
+ @service notify;
+
+ // =methods
+
+ /**
+ * Loads all hosts under the current host catalog and it's parent project scope.
+ * @return {Promise{[HostModel]}}
+ */
+ async model() {
+ return this.store.findAll('host', this.adapterOptions());
+ }
+
+ // =actions
+
+ /**
+ * Rollback changes on a host.
+ * @param {HostModel} host
+ */
+ @action
+ cancel(host) {
+ const { isNew } = host;
+ host.rollbackAttributes();
+ if (isNew) this.transitionTo('scopes.scope.projects.project.host-catalogs.host-catalog.hosts');
+ }
+
+ /**
+ * Handle save of a host.
+ * @param {HostModel} host
+ * @param {Event} e
+ */
+ @action
+ async save(host) {
+ try {
+ const { isNew } = host;
+ await host.save(this.adapterOptions());
+ this.refresh();
+ this.notify.success(
+ this.intl.t(isNew ? 'notify.create-success' : 'notify.save-success')
+ );
+ this.transitionTo('scopes.scope.projects.project.host-catalogs.host-catalog.hosts.host', host);
+ } catch (error) {
+ // TODO: replace with translated strings
+ this.notify.error(error.message, { closeAfter: null });
+ }
+ }
+
+ /**
+ * Delete host in current scope and redirect to index.
+ * @param {HostModel} host
+ */
+ @action
+ async delete(host) {
+ try {
+ await host.destroyRecord(this.adapterOptions());
+ this.refresh();
+ this.notify.success(this.intl.t('notify.delete-success'));
+ this.transitionTo('scopes.scope.projects.project.host-catalogs.host-catalog.hosts');
+ } catch (error) {
+ // TODO: replace with translated strings
+ this.notify.error(error.message, { closeAfter: null });
+ }
+ }
+
+ /**
+ * Configure adapter options using current host catalog scope and it's parent project scope.
+ * @return {object}
+ */
+ adapterOptions() {
+ const scopeID = this.modelFor('scopes.scope.projects.project').id;
+ const hostCatalogID = this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog').id;
+ return { adapterOptions : { scopeID, hostCatalogID } };
+ }
}
diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host.js
index 8668b3101..671ca781b 100644
--- a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host.js
+++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host.js
@@ -1,4 +1,47 @@
import Route from '@ember/routing/route';
export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsHostRoute extends Route {
+ // =methods
+
+ /**
+ * Load a host using current host-catalog and it's parent project scope.
+ * @param {object} params
+ * @param {string} params.host_id
+ * @return {HostModel}
+ */
+ async model({ host_id }) {
+ const { id: scopeID } = this.modelFor('scopes.scope.projects.project');
+ const hostCatalogID = this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog').id;
+ return this.store.findRecord('host', host_id, {
+ adapterOptions: { scopeID, hostCatalogID }
+ });
+ }
+
+ /**
+ * Renders the host specific templates for header, navigation, and action page sections.
+ * @override
+ * @param {object} controller
+ * @param {object} model
+ */
+ renderTemplate(controller, model) {
+ this.render('scopes/scope/projects/project/host-catalogs/host-catalog/hosts');
+
+ this.render('scopes/scope/projects/project/host-catalogs/host-catalog/hosts/-header', {
+ into: 'scopes/scope/projects/project/host-catalogs/host-catalog',
+ outlet: 'header',
+ model: model
+ });
+
+ this.render('scopes/scope/projects/project/host-catalogs/host-catalog/hosts/-navigation', {
+ into: 'scopes/scope/projects/project/host-catalogs/host-catalog',
+ outlet: 'navigation',
+ model: model
+ });
+
+ this.render('scopes/scope/projects/project/host-catalogs/host-catalog/hosts/-actions', {
+ into: 'scopes/scope/projects/project/host-catalogs/host-catalog',
+ outlet: 'actions',
+ model: model
+ });
+ }
}
diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host/index.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host/index.js
new file mode 100644
index 000000000..a270ffacc
--- /dev/null
+++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host/index.js
@@ -0,0 +1,4 @@
+import Route from '@ember/routing/route';
+
+export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsHostIndexRoute extends Route {
+}
diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/index.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/index.js
new file mode 100644
index 000000000..96bba9927
--- /dev/null
+++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/index.js
@@ -0,0 +1,4 @@
+import Route from '@ember/routing/route';
+
+export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsIndexRoute extends Route {
+}
diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/new.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/new.js
index 9d002b717..39f90d1bb 100644
--- a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/new.js
+++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/new.js
@@ -1,4 +1,46 @@
import Route from '@ember/routing/route';
export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsNewRoute extends Route {
+
+ // =methods
+
+ /**
+ * Creates a new unsaved host in current host catalog scope.
+ * @return {HostModel}
+ */
+ model() {
+ const scopeModel = this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog');
+ return this.store.createRecord('host', {
+ type: 'static',
+ scopeModel
+ });
+ }
+
+ /**
+ * Renders new host specific templates for header, navigation, and action page sections.
+ * @override
+ * @param {object} controller
+ * @param {object} model
+ */
+ renderTemplate(controller, model) {
+ super.renderTemplate(...arguments);
+
+ this.render('scopes/scope/projects/project/host-catalogs/host-catalog/hosts/new/-header', {
+ into: 'scopes/scope/projects/project/host-catalogs/host-catalog',
+ outlet: 'header',
+ model: model
+ });
+
+ this.render('_empty', {
+ into: 'scopes/scope/projects/project/host-catalogs/host-catalog',
+ outlet: 'navigation',
+ model: model
+ });
+
+ this.render('_empty', {
+ into: 'scopes/scope/projects/project/host-catalogs/host-catalog',
+ outlet: 'actions',
+ model: model
+ });
+ }
}
diff --git a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/-actions.hbs b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/-actions.hbs
index 9f1032438..50cd97fe0 100644
--- a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/-actions.hbs
+++ b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/-actions.hbs
@@ -1,4 +1,10 @@
+
+ {{t "actions.add-host"}}
+
{{t 'titles.host-sets'}}
+
+ {{t 'titles.hosts'}}
+
diff --git a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts.hbs b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts.hbs
index e2147cab0..863e34ea9 100644
--- a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts.hbs
+++ b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts.hbs
@@ -1 +1,3 @@
+{{title (t "resources.hosts")}}
+
{{outlet}}
\ No newline at end of file
diff --git a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/-actions.hbs b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/-actions.hbs
new file mode 100644
index 000000000..a63265116
--- /dev/null
+++ b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/-actions.hbs
@@ -0,0 +1,9 @@
+
+
+ {{t 'actions.delete-host'}}
+
+
\ No newline at end of file
diff --git a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/-header.hbs b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/-header.hbs
new file mode 100644
index 000000000..3187158d1
--- /dev/null
+++ b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/-header.hbs
@@ -0,0 +1 @@
+{{t "resources.host"}}
\ No newline at end of file
diff --git a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/-navigation.hbs b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/-navigation.hbs
new file mode 100644
index 000000000..d79e3afa2
--- /dev/null
+++ b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/-navigation.hbs
@@ -0,0 +1,5 @@
+
+
+ {{t 'titles.details'}}
+
+
\ No newline at end of file
diff --git a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host/index.hbs
new file mode 100644
index 000000000..6cc780607
--- /dev/null
+++ b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host/index.hbs
@@ -0,0 +1,5 @@
+
diff --git a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/index.hbs
new file mode 100644
index 000000000..7905988e5
--- /dev/null
+++ b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/index.hbs
@@ -0,0 +1,48 @@
+{{#if @model}}
+
+
+
+
+ {{t "form.label.name"}}
+ {{t "form.label.type"}}
+ {{t "form.label.id"}}
+
+
+
+ {{#each @model as |host|}}
+
+
+
+ {{host.displayName}}
+
+ {{host.description}}
+
+
+ {{host.type}}
+
+
+ {{host.id}}
+
+
+ {{/each}}
+
+
+
+{{else}}
+
+
+
+
+ {{t "descriptions.hosts-welcome"}}
+
+
+
+ {{t "titles.new"}}
+
+
+
+
+{{/if}}
diff --git a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/new.hbs b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/new.hbs
index e2147cab0..29bf7404f 100644
--- a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/new.hbs
+++ b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/new.hbs
@@ -1 +1,7 @@
-{{outlet}}
\ No newline at end of file
+{{title (t 'titles.new')}}
+
+
\ No newline at end of file
diff --git a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/new/-header.hbs b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/new/-header.hbs
new file mode 100644
index 000000000..ace8ccb08
--- /dev/null
+++ b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/new/-header.hbs
@@ -0,0 +1 @@
+{{t "titles.new"}}
\ No newline at end of file
diff --git a/ui/core/tests/acceptance/host-sets-test.js b/ui/core/tests/acceptance/host-sets-test.js
index f7ba7226d..7e855a326 100644
--- a/ui/core/tests/acceptance/host-sets-test.js
+++ b/ui/core/tests/acceptance/host-sets-test.js
@@ -55,7 +55,7 @@ module('Acceptance | host sets', function (hooks) {
assert.expect(0);
});
- test('saving an existing auth method with invalid fields displays error messages', async function (assert) {
+ test('saving an existing host set with invalid fields displays error messages', async function (assert) {
assert.expect(0);
});
});
diff --git a/ui/core/tests/acceptance/hosts-test.js b/ui/core/tests/acceptance/hosts-test.js
new file mode 100644
index 000000000..cd5c2c604
--- /dev/null
+++ b/ui/core/tests/acceptance/hosts-test.js
@@ -0,0 +1,114 @@
+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 | hosts', function (hooks) {
+ setupApplicationTest(hooks);
+ setupMirage(hooks);
+
+ const instances = {
+ scopes: {
+ global: null,
+ org: null,
+ project: null,
+ hostCatalog: null
+ },
+ host: null
+ };
+ const urls = {
+ orgScope: null,
+ projects: null,
+ project: null,
+ hostCatalogs: null,
+ hostCatalog: null,
+ hosts: 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', {
+ scope: {
+ id: instances.scopes.project.id,
+ type: instances.scopes.project.type
+ }
+ });
+
+ instances.host = this.server.create('host', {
+ 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.hosts = `${urls.hostCatalog}/host`;
+ });
+
+ test('visiting host', async function (assert) {
+ assert.expect(1);
+ authenticateSession();
+ await visit(urls.hosts);
+ await a11yAudit();
+ assert.equal(currentURL(), urls.hosts);
+ });
+
+ test('can navigate to a host form', async function (assert) {
+ assert.expect(0);
+ });
+
+ test('can update a host and save changes', async function (assert) {
+ assert.expect(0);
+ });
+
+ test('can update a host and cancel changes', async function (assert) {
+ assert.expect(0);
+ });
+
+ test('can create new host', async function (assert) {
+ assert.expect(0);
+ });
+
+ test('can cancel new host creation', async function (assert) {
+ assert.expect(0);
+ });
+
+ test('saving a new host with invalid fields displays error messages', async function (assert) {
+ assert.expect(0);
+ });
+
+ test('errors are displayed when save on auth method fails', async function (assert) {
+ assert.expect(0);
+ });
+
+ test('errors are displayed when delete on a host fails', async function (assert) {
+ assert.expect(0);
+ });
+
+ test('saving an existing host with invalid fields displays error messages', async function (assert) {
+ assert.expect(0);
+ });
+});
diff --git a/ui/core/tests/integration/components/form/host/index-test.js b/ui/core/tests/integration/components/form/host/index-test.js
new file mode 100644
index 000000000..3bc90b275
--- /dev/null
+++ b/ui/core/tests/integration/components/form/host/index-test.js
@@ -0,0 +1,26 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module('Integration | Component | form/host/index', function(hooks) {
+ setupRenderingTest(hooks);
+
+ test('it renders', async function(assert) {
+ // Set any properties with this.set('myProperty', 'value');
+ // Handle any actions with this.set('myAction', function(val) { ... });
+
+ await render(hbs``);
+
+ assert.equal(this.element.textContent.trim(), '');
+
+ // Template block usage:
+ await render(hbs`
+
+ template block text
+
+ `);
+
+ assert.equal(this.element.textContent.trim(), 'template block text');
+ });
+});
diff --git a/ui/core/tests/unit/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host/index-test.js b/ui/core/tests/unit/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host/index-test.js
new file mode 100644
index 000000000..58704fe8c
--- /dev/null
+++ b/ui/core/tests/unit/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host/index-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/hosts/host/index', function(hooks) {
+ setupTest(hooks);
+
+ test('it exists', function(assert) {
+ let route = this.owner.lookup('route:scopes/scope/projects/project/host-catalogs/host-catalog/hosts/host/index');
+ assert.ok(route);
+ });
+});
diff --git a/ui/core/tests/unit/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/index-test.js b/ui/core/tests/unit/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/index-test.js
new file mode 100644
index 000000000..151e905b5
--- /dev/null
+++ b/ui/core/tests/unit/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts/index-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/hosts/index', function(hooks) {
+ setupTest(hooks);
+
+ test('it exists', function(assert) {
+ let route = this.owner.lookup('route:scopes/scope/projects/project/host-catalogs/host-catalog/hosts/index');
+ assert.ok(route);
+ });
+});
diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml
index 125b3b75c..434d78ee8 100644
--- a/ui/core/translations/en-us.yaml
+++ b/ui/core/translations/en-us.yaml
@@ -16,7 +16,9 @@ actions:
delete-host-catalog: Delete host catalog
delete-auth-method: Delete auth method
delete-host-set: Delete host set
+ delete-host: Delete host
add-host-set: Create Host Set
+ add-host: Create Host
auth:
titles:
no-scopes: No Scopes Available
@@ -31,6 +33,9 @@ auth:
host-set:
types:
static: Static
+host:
+ types:
+ static: Static
resources:
user: User
users: Users
@@ -48,6 +53,8 @@ resources:
auth-methods: Auth Methods
host-set: Host Set
host-sets: Host Sets
+ hosts: Hosts
+ host: Host
titles:
iam: IAM
new: New
@@ -60,6 +67,7 @@ titles:
projects-welcome: Welcome to Projects
host-catalogs-welcome: Welcome to Host Catalogs
host-sets-welcome: Welcome to Host Sets
+ hosts-welcome: Welcome to Hosts
users-welcome: Welcome to Users
roles-welcome: Welcome to Roles
groups-welcome: Welcome to Groups
@@ -68,6 +76,7 @@ titles:
new-grant: New Grant
principals: Principals
host-sets: Host Sets
+ hosts: Hosts
global: Global
descriptions:
host-catalogs: Overview of collections of hosts and host sets.
@@ -75,6 +84,7 @@ descriptions:
projects-welcome: Projects allow you to create and manage host catalogs. To start, create a project.
host-catalogs-welcome: Host catalogs allow you to configure to collect and create hosts and host sets. To start, create a host catalog.
host-sets-welcome: Configure a static host set in this host catalog.
+ hosts-welcome: Configure a static host in this host catalog.
users-welcome: Users are authorized to access Boundary.
roles-welcome: Roles are collections of capabilities that can be granted to user and/or groups.
groups-welcome: Groups are collections of users.