Merge branch 'develop' into add-target-type
This commit is contained in:
49 files changed
+312
-217
No files matched your search
@@ -0,0 +1,13 @@
|
||||
import ApplicationAdapter from './application';
|
||||
|
||||
export default class HostCatalogAdapter extends ApplicationAdapter {
|
||||
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* Host catalogs use the new, unprefixed pathing style.
|
||||
* @override
|
||||
*/
|
||||
hasScopePrefix = false;
|
||||
|
||||
}
|
||||
@@ -7,32 +7,12 @@ export default class HostSetAdapter extends ApplicationAdapter {
|
||||
|
||||
@service store;
|
||||
|
||||
// =methods
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* Append a host catalog URL ahead of the host sets path if `hostCatalogID` is
|
||||
* passed via adapter options. Otherwise, generate the prefix as normal.
|
||||
*
|
||||
* TODO: generalize the interface to resource-prefixed URLs by accepting
|
||||
* a modelName and an ID, rather than looking for a known key.
|
||||
*
|
||||
* Host sets use the new, unprefixed pathing style.
|
||||
* @override
|
||||
* @param {string} path
|
||||
* @param {string} parentURL
|
||||
* @param {string} modelName
|
||||
* @param {string} id
|
||||
* @param {object} snapshot
|
||||
* @return {string} urlPrefix
|
||||
*/
|
||||
urlPrefix(path, parentURL, modelName, id, snapshot) {
|
||||
const hostCatalogID = snapshot?.adapterOptions?.hostCatalogID;
|
||||
if (hostCatalogID) {
|
||||
const hostCatalogAdapter = this.store.adapterFor('host-catalog');
|
||||
return hostCatalogAdapter
|
||||
._buildPrefixedURL('host-catalog', hostCatalogID, snapshot);
|
||||
} else {
|
||||
return super.urlPrefix(...arguments);
|
||||
}
|
||||
}
|
||||
hasScopePrefix = false;
|
||||
|
||||
}
|
||||
@@ -7,32 +7,12 @@ export default class HostAdapter extends ApplicationAdapter {
|
||||
|
||||
@service store;
|
||||
|
||||
// =methods
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* Append a host catalog URL ahead of the host path if `hostCatalogID` is
|
||||
* passed via adapter options. Otherwise, generate the prefix as normal.
|
||||
*
|
||||
* TODO: generalize the interface to resource-prefixed URLs by accepting
|
||||
* a modelName and an ID, rather than looking for a known key.
|
||||
*
|
||||
* Hosts use the new, unprefixed pathing style.
|
||||
* @override
|
||||
* @param {string} path
|
||||
* @param {string} parentURL
|
||||
* @param {string} modelName
|
||||
* @param {string} id
|
||||
* @param {object} snapshot
|
||||
* @return {string} urlPrefix
|
||||
*/
|
||||
urlPrefix(path, parentURL, modelName, id, snapshot) {
|
||||
const hostCatalogID = snapshot?.adapterOptions?.hostCatalogID;
|
||||
if (hostCatalogID) {
|
||||
const hostCatalogAdapter = this.store.adapterFor('host-catalog');
|
||||
return hostCatalogAdapter
|
||||
._buildPrefixedURL('host-catalog', hostCatalogID, snapshot);
|
||||
} else {
|
||||
return super.urlPrefix(...arguments);
|
||||
}
|
||||
}
|
||||
hasScopePrefix = false;
|
||||
|
||||
}
|
||||
@@ -15,7 +15,6 @@ export default class GeneratedHostSetModel extends BaseModel {
|
||||
|
||||
@attr('string', {
|
||||
description: 'The owning host catalog ID.',
|
||||
readOnly: true
|
||||
}) host_catalog_id;
|
||||
|
||||
@attr('string', {
|
||||
|
||||
@@ -12,6 +12,10 @@ export default class GeneratedHostModel extends BaseModel {
|
||||
description: 'The type of the resource, to help differentiate schemas'
|
||||
}) type;
|
||||
|
||||
@attr('string', {
|
||||
description: 'The owning host catalog ID.',
|
||||
}) host_catalog_id;
|
||||
|
||||
@attr('string', {
|
||||
description: 'Optional name for identification purposes'
|
||||
}) name;
|
||||
@@ -35,8 +39,4 @@ export default class GeneratedHostModel extends BaseModel {
|
||||
})
|
||||
version;
|
||||
|
||||
@attr('string', {
|
||||
description: 'The address (DNS or IP name) used to reach the host'
|
||||
}) address;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import Fragment from 'ember-data-model-fragments/fragment';
|
||||
import { attr } from '@ember-data/model';
|
||||
|
||||
export default class FragmentHostAttributesModel extends Fragment {
|
||||
|
||||
@attr('string', {
|
||||
description: 'The address (DNS or IP name) used to reach the host'
|
||||
}) address;
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import GeneratedHostSetModel from '../generated/models/host-set';
|
||||
import { fragmentArray } from 'ember-data-model-fragments/attributes';
|
||||
//import { computed } from '@ember/object';
|
||||
|
||||
export default class HostSetModel extends GeneratedHostSetModel {
|
||||
|
||||
@@ -12,18 +11,6 @@ export default class HostSetModel extends GeneratedHostSetModel {
|
||||
*/
|
||||
@fragmentArray('fragment-string', {readOnly: true}) host_ids;
|
||||
|
||||
// TODO this is here in case we want it in the future,
|
||||
// especially for the target / add host sets workflow
|
||||
/**
|
||||
* Returns the host catalog instance associated with this host set if
|
||||
* it is already loaded into the store.
|
||||
* @type {?HostCatalogModel}
|
||||
*/
|
||||
// @computed('host_catalog_id')
|
||||
// get hostCatalog() {
|
||||
// return this.store.peekRecord('host-catalog', this.host_catalog_id);
|
||||
// }
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
import GeneratedHostModel from '../generated/models/host';
|
||||
import { fragment } from 'ember-data-model-fragments/attributes';
|
||||
|
||||
export default class HostModel extends GeneratedHostModel {}
|
||||
export default class HostModel extends GeneratedHostModel {
|
||||
|
||||
/**
|
||||
* Attributes of this resource, if any, represented as a JSON fragment.
|
||||
* @type {FragmentHostAttributesModel}
|
||||
*/
|
||||
@fragment('fragment-host-attributes', { defaultValue: {} }) attributes;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import ApplicationSerializer from './application';
|
||||
|
||||
export default class HostCatalogSerializer extends ApplicationSerializer {
|
||||
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* Serialized the scope ID into the `scope_id` field.
|
||||
* @type {boolean}
|
||||
*/
|
||||
serializeScopeID = true;
|
||||
|
||||
}
|
||||
@@ -2,6 +2,14 @@ import ApplicationSerializer from './application';
|
||||
|
||||
export default class HostSetSerializer extends ApplicationSerializer {
|
||||
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* Serialized the scope ID into the `scope_id` field.
|
||||
* @type {boolean}
|
||||
*/
|
||||
serializeScopeID = true;
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import ApplicationSerializer from './application';
|
||||
|
||||
export default class HostSerializer extends ApplicationSerializer {
|
||||
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* Serialized the scope ID into the `scope_id` field.
|
||||
* @type {boolean}
|
||||
*/
|
||||
serializeScopeID = true;
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/adapters/host-catalog';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/models/fragment-host-attributes';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/serializers/host-catalog';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/serializers/host';
|
||||
@@ -0,0 +1,12 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Adapter | host catalog', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let adapter = this.owner.lookup('adapter:host-catalog');
|
||||
assert.ok(adapter);
|
||||
});
|
||||
});
|
||||
@@ -6,23 +6,17 @@ module('Unit | Adapter | host set', function(hooks) {
|
||||
|
||||
test('it generates correct complete URLs', function (assert) {
|
||||
assert.expect(2);
|
||||
const scopeID = 'o_1';
|
||||
const hostCatalogID = 'hc_098';
|
||||
const method = 'my-custom-method';
|
||||
const mockSnapshot = {
|
||||
adapterOptions: {
|
||||
scopeID,
|
||||
method
|
||||
}
|
||||
};
|
||||
const mockSnapshot = { adapterOptions: { method } };
|
||||
const adapter = this.owner.lookup('adapter:host-set');
|
||||
// Without hostCatalogID...
|
||||
let url = adapter.buildURL('host-set', null, mockSnapshot, 'findAll');
|
||||
assert.equal(url, '/v1/scopes/o_1/host-sets:my-custom-method');
|
||||
assert.equal(url, '/v1/host-sets:my-custom-method');
|
||||
// With hostCatalogID...
|
||||
mockSnapshot.adapterOptions.hostCatalogID = hostCatalogID;
|
||||
url = adapter.buildURL('host-set', null, mockSnapshot, 'findAll');
|
||||
assert.equal(url, '/v1/scopes/o_1/host-catalogs/hc_098/host-sets:my-custom-method');
|
||||
assert.equal(url, '/v1/host-sets:my-custom-method');
|
||||
});
|
||||
|
||||
});
|
||||
@@ -4,25 +4,9 @@ import { setupTest } from 'ember-qunit';
|
||||
module('Unit | Adapter | host', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it generates correct complete URLs', function (assert) {
|
||||
assert.expect(2);
|
||||
const scopeID = 'o_1';
|
||||
const hostCatalogID = 'hc_098';
|
||||
const method = 'my-custom-method';
|
||||
const mockSnapshot = {
|
||||
adapterOptions: {
|
||||
scopeID,
|
||||
method
|
||||
}
|
||||
};
|
||||
const adapter = this.owner.lookup('adapter:host');
|
||||
// Without hostCatalogID...
|
||||
let url = adapter.buildURL('host', null, mockSnapshot, 'findAll');
|
||||
assert.equal(url, '/v1/scopes/o_1/hosts:my-custom-method');
|
||||
// With hostCatalogID...
|
||||
mockSnapshot.adapterOptions.hostCatalogID = hostCatalogID;
|
||||
url = adapter.buildURL('host', null, mockSnapshot, 'findAll');
|
||||
assert.equal(url, '/v1/scopes/o_1/host-catalogs/hc_098/hosts:my-custom-method');
|
||||
test('it exists', function(assert) {
|
||||
let adapter = this.owner.lookup('adapter:host');
|
||||
assert.ok(adapter);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -10,4 +10,15 @@ module('Unit | Model | host', function(hooks) {
|
||||
let model = store.createRecord('host', {});
|
||||
assert.ok(model);
|
||||
});
|
||||
|
||||
test('it contains attributes', function(assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let model = store.createRecord('host', {
|
||||
type: 'static',
|
||||
attributes: {
|
||||
address: '127.0.0.1'
|
||||
}
|
||||
});
|
||||
assert.equal(model.attributes.address, '127.0.0.1');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Serializer | host catalog', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let serializer = store.serializerFor('host-catalog');
|
||||
|
||||
assert.ok(serializer);
|
||||
});
|
||||
|
||||
test('it serializes records', function(assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let record = store.createRecord('host-catalog', {});
|
||||
|
||||
let serializedRecord = record.serialize();
|
||||
|
||||
assert.ok(serializedRecord);
|
||||
});
|
||||
});
|
||||
@@ -11,6 +11,7 @@ module('Unit | Serializer | host set', function(hooks) {
|
||||
const record = store.createRecord('host-set', {
|
||||
name: 'Host Set 1',
|
||||
description: 'Description',
|
||||
host_catalog_id: '123',
|
||||
version: 1
|
||||
});
|
||||
const snapshot = record._createSnapshot();
|
||||
@@ -19,6 +20,7 @@ module('Unit | Serializer | host set', function(hooks) {
|
||||
assert.deepEqual(serializedRecord, {
|
||||
name: 'Host Set 1',
|
||||
description: 'Description',
|
||||
host_catalog_id: '123',
|
||||
version: 1
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Serializer | host', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let serializer = store.serializerFor('host');
|
||||
|
||||
assert.ok(serializer);
|
||||
});
|
||||
|
||||
test('it serializes records', function(assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let record = store.createRecord('host', {});
|
||||
|
||||
let serializedRecord = record.serialize();
|
||||
|
||||
assert.ok(serializedRecord);
|
||||
});
|
||||
});
|
||||
@@ -41,7 +41,7 @@
|
||||
onChange={{fn @toggleHost option.host}} />
|
||||
</row.cell>
|
||||
<row.cell>{{option.host.name}}</row.cell>
|
||||
<row.cell>{{option.host.address}}</row.cell>
|
||||
<row.cell>{{option.host.attributes.address}}</row.cell>
|
||||
</body.row>
|
||||
{{/each}}
|
||||
</table.body>
|
||||
|
||||
@@ -47,6 +47,24 @@
|
||||
{{/if}}
|
||||
</form.textarea>
|
||||
|
||||
<form.input
|
||||
@name="address"
|
||||
@type="text"
|
||||
@value={{@model.attributes.address}}
|
||||
@label={{t "form.label.address"}}
|
||||
@error={{@model.errors.name}}
|
||||
readonly={{false}}
|
||||
as |field|>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@submitText={{t "actions.save"}}
|
||||
|
||||
@@ -13,12 +13,12 @@ export default class ScopesScopeProjectsProjectHostCatalogsRoute extends Route {
|
||||
|
||||
|
||||
/**
|
||||
* Loads all scopes under the current scope.
|
||||
* Loads all host catalogs under the current scope.
|
||||
* @return {Promise{[HostCatalogModel]}}
|
||||
*/
|
||||
async model() {
|
||||
const scopeID = this.modelFor('scopes.scope.projects.project').id;
|
||||
return this.store.findAll('host-catalog', { adapterOptions: { scopeID } });
|
||||
const { id: scope_id } = this.modelFor('scopes.scope.projects.project');
|
||||
return this.store.query('host-catalog', { scope_id });
|
||||
}
|
||||
|
||||
// =actions
|
||||
|
||||
@@ -11,10 +11,7 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogRoute exte
|
||||
* @return {HostCatalogModel}
|
||||
*/
|
||||
async model({ host_catalog_id }) {
|
||||
const { id: scopeID } = this.modelFor('scopes.scope');
|
||||
return this.store.findRecord('host-catalog', host_catalog_id, {
|
||||
adapterOptions: { scopeID },
|
||||
});
|
||||
return this.store.findRecord('host-catalog', host_catalog_id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+8
-19
@@ -8,28 +8,16 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsRo
|
||||
@service intl;
|
||||
@service notify;
|
||||
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* Configure adapter options using current host catalog and
|
||||
* the current project scope.
|
||||
* @return {object}
|
||||
*/
|
||||
get 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 } };
|
||||
}
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Loads all host-sets under the current host catalog and it's parent scope.
|
||||
* @return {Promise{[HostSetModel]}}
|
||||
*/
|
||||
async model() {
|
||||
this.store.unloadAll('host-set');
|
||||
return this.store.findAll('host-set', this.adapterOptions);
|
||||
model() {
|
||||
const { id: host_catalog_id } =
|
||||
this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog');
|
||||
return this.store.query('host-set', { host_catalog_id });
|
||||
}
|
||||
|
||||
// =actions
|
||||
@@ -54,11 +42,12 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsRo
|
||||
async save(hostSet) {
|
||||
try {
|
||||
const { isNew } = hostSet;
|
||||
await hostSet.save(this.adapterOptions);
|
||||
await hostSet.save();
|
||||
await this.transitionTo('scopes.scope.projects.project.host-catalogs.host-catalog.host-sets.host-set', hostSet);
|
||||
await 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.host-sets.host-set', hostSet);
|
||||
} catch (error) {
|
||||
// TODO: replace with translated strings
|
||||
this.notify.error(error.message, { closeAfter: null });
|
||||
@@ -72,7 +61,7 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsRo
|
||||
@action
|
||||
async delete(hostSet) {
|
||||
try {
|
||||
await hostSet.destroyRecord(this.adapterOptions);
|
||||
await hostSet.destroyRecord();
|
||||
this.notify.success(this.intl.t('notify.delete-success'));
|
||||
this.transitionTo('scopes.scope.projects.project.host-catalogs.host-catalog.host-sets');
|
||||
} catch (error) {
|
||||
|
||||
+1
-6
@@ -10,12 +10,7 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsHo
|
||||
* @return {HostSetModel}
|
||||
*/
|
||||
async model({ host_set_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-set', host_set_id, {
|
||||
reload: true,
|
||||
adapterOptions: { scopeID, hostCatalogID }
|
||||
});
|
||||
return this.store.findRecord('host-set', host_set_id, { reload: true });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+4
-7
@@ -24,11 +24,10 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsHo
|
||||
* @return {Promise{HostSetModel,[HostModel]}}
|
||||
*/
|
||||
async model() {
|
||||
const scopeID = this.modelFor('scopes.scope.projects.project').id;
|
||||
const hostCatalogID = this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog').id;
|
||||
const { id: host_catalog_id } = this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog');
|
||||
return hash({
|
||||
hostSet: this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog.host-sets.host-set'),
|
||||
hosts: this.store.findAll('host', { adapterOptions: { scopeID, hostCatalogID } })
|
||||
hosts: this.store.query('host', { host_catalog_id })
|
||||
});
|
||||
}
|
||||
|
||||
@@ -84,13 +83,11 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsHo
|
||||
@action
|
||||
async addHosts(hostSet, hostIDs) {
|
||||
try {
|
||||
const scopeID = this.modelFor('scopes.scope.projects.project').id;
|
||||
const hostCatalogID = this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog').id;
|
||||
await hostSet.addHosts(hostIDs, { adapterOptions : { scopeID, hostCatalogID } });
|
||||
await hostSet.addHosts(hostIDs);
|
||||
await this.replaceWith('scopes.scope.projects.project.host-catalogs.host-catalog.host-sets.host-set.hosts');
|
||||
this.notify.success(
|
||||
this.intl.t('notify.save-success')
|
||||
);
|
||||
this.replaceWith('scopes.scope.projects.project.host-catalogs.host-catalog.host-sets.host-set.hosts');
|
||||
} catch (error) {
|
||||
// TODO: replace with translated strings
|
||||
this.notify.error(error.message, { closeAfter: null });
|
||||
|
||||
+1
-10
@@ -12,25 +12,16 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsHo
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Empty out any previously loaded hosts.
|
||||
*/
|
||||
beforeModel() {
|
||||
this.store.unloadAll('host');
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all hosts under the current host set.
|
||||
* @return {Promise{HostSetModel,[HostModel]}}
|
||||
*/
|
||||
async model() {
|
||||
const scopeID = this.modelFor('scopes.scope.projects.project').id;
|
||||
const hostCatalogID = this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog').id;
|
||||
const hostSet = this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog.host-sets.host-set');
|
||||
return hash({
|
||||
hostSet,
|
||||
hosts: all(hostSet.host_ids.map(host =>
|
||||
this.store.findRecord('host', host.value, { adapterOptions: { scopeID, hostCatalogID } })
|
||||
this.store.findRecord('host', host.value, { reload: true })
|
||||
))
|
||||
});
|
||||
}
|
||||
|
||||
+3
-2
@@ -9,10 +9,11 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsNe
|
||||
* @return {HostSetModel}
|
||||
*/
|
||||
model() {
|
||||
const scopeModel = this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog');
|
||||
const { id: host_catalog_id } =
|
||||
this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog');
|
||||
return this.store.createRecord('host-set', {
|
||||
type: 'static',
|
||||
scopeModel
|
||||
host_catalog_id
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+8
-16
@@ -14,8 +14,10 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsRoute
|
||||
* 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());
|
||||
model() {
|
||||
const { id: host_catalog_id } =
|
||||
this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog');
|
||||
return this.store.query('host', { host_catalog_id });
|
||||
}
|
||||
|
||||
// =actions
|
||||
@@ -40,12 +42,12 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsRoute
|
||||
async save(host) {
|
||||
try {
|
||||
const { isNew } = host;
|
||||
await host.save(this.adapterOptions());
|
||||
this.refresh();
|
||||
await host.save();
|
||||
await this.transitionTo('scopes.scope.projects.project.host-catalogs.host-catalog.hosts.host', host);
|
||||
await 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 });
|
||||
@@ -59,7 +61,7 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsRoute
|
||||
@action
|
||||
async delete(host) {
|
||||
try {
|
||||
await host.destroyRecord(this.adapterOptions());
|
||||
await host.destroyRecord();
|
||||
this.refresh();
|
||||
this.notify.success(this.intl.t('notify.delete-success'));
|
||||
this.transitionTo('scopes.scope.projects.project.host-catalogs.host-catalog.hosts');
|
||||
@@ -68,14 +70,4 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsRoute
|
||||
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 } };
|
||||
}
|
||||
}
|
||||
+1
-5
@@ -10,11 +10,7 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsHostR
|
||||
* @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 }
|
||||
});
|
||||
return this.store.findRecord('host', host_id, { reload: true });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+3
-2
@@ -9,10 +9,11 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsNewRo
|
||||
* @return {HostModel}
|
||||
*/
|
||||
model() {
|
||||
const scopeModel = this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog');
|
||||
const { id: host_catalog_id } =
|
||||
this.modelFor('scopes.scope.projects.project.host-catalogs.host-catalog');
|
||||
return this.store.createRecord('host', {
|
||||
type: 'static',
|
||||
scopeModel
|
||||
host_catalog_id
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -13,10 +13,9 @@ export default class ScopesScopeProjectsProjectTargetsTargetAddHostSetsRoute ext
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Empty out any previously loaded host catalogs and host sets.
|
||||
* Empty out any previously loaded host sets.
|
||||
*/
|
||||
beforeModel() {
|
||||
this.store.unloadAll('host-catalog');
|
||||
this.store.unloadAll('host-set');
|
||||
}
|
||||
|
||||
@@ -27,12 +26,10 @@ export default class ScopesScopeProjectsProjectTargetsTargetAddHostSetsRoute ext
|
||||
async model() {
|
||||
const target =
|
||||
this.modelFor('scopes.scope.projects.project.targets.target');
|
||||
const { scopeID } = target;
|
||||
const hostCatalogs =
|
||||
await this.store.findAll('host-catalog', { adapterOptions: { scopeID } });
|
||||
await all(hostCatalogs.map(({ id: hostCatalogID }) =>
|
||||
this.store
|
||||
.findAll('host-set', { adapterOptions: { scopeID, hostCatalogID } })
|
||||
const { id: scope_id } = this.modelFor('scopes.scope.projects.project');
|
||||
const hostCatalogs = await this.store.query('host-catalog', { scope_id });
|
||||
await all(hostCatalogs.map(({ id: host_catalog_id }) =>
|
||||
this.store.query('host-set', { host_catalog_id })
|
||||
));
|
||||
const hostSets = this.store.peekAll('host-set');
|
||||
return {
|
||||
|
||||
+4
@@ -6,6 +6,7 @@
|
||||
<row.headerCell>{{t "form.label.name"}}</row.headerCell>
|
||||
<row.headerCell>{{t "form.label.type"}}</row.headerCell>
|
||||
<row.headerCell>{{t "form.label.id"}}</row.headerCell>
|
||||
<row.headerCell>{{t "form.label.address"}}</row.headerCell>
|
||||
</header.row>
|
||||
</table.header>
|
||||
<table.body as |body|>
|
||||
@@ -26,6 +27,9 @@
|
||||
<row.cell>
|
||||
<code>{{host.id}}</code>
|
||||
</row.cell>
|
||||
<row.cell>
|
||||
<code>{{host.attributes.address}}</code>
|
||||
</row.cell>
|
||||
</body.row>
|
||||
{{/each}}
|
||||
</table.body>
|
||||
|
||||
+22
-18
@@ -147,40 +147,44 @@ export default function() {
|
||||
// Other resources
|
||||
// host-catalog
|
||||
|
||||
this.get('/scopes/:scope_id/host-catalogs');
|
||||
this.post('/scopes/:scope_id/host-catalogs');
|
||||
this.get('/scopes/:scope_id/host-catalogs/:id');
|
||||
this.patch('/scopes/:scope_id/host-catalogs/:id');
|
||||
this.del('/scopes/:scope_id/host-catalogs/:id');
|
||||
this.get('/host-catalogs', ({ hostCatalogs }, { queryParams: { scope_id: scopeId } }) => {
|
||||
return hostCatalogs.where({ scopeId });
|
||||
});
|
||||
this.post('/host-catalogs');
|
||||
this.get('/host-catalogs/:id');
|
||||
this.patch('/host-catalogs/:id');
|
||||
this.del('/host-catalogs/:id');
|
||||
|
||||
// host
|
||||
|
||||
this.get('/scopes/:scope_id/host-catalogs/:hostCatalogId/hosts', function ({ hosts }, { params: { hostCatalogId } }) {
|
||||
this.get('/hosts', function ({ hosts }, { queryParams: { host_catalog_id: hostCatalogId } }) {
|
||||
return hosts.where({ hostCatalogId });
|
||||
});
|
||||
this.post('/scopes/:scope_id/host-catalogs/:hostCatalogId/hosts', function ({ hosts }, { params: { hostCatalogId } }) {
|
||||
this.post('/hosts', function ({ hostCatalogs, hosts }) {
|
||||
const attrs = this.normalizedRequestAttrs();
|
||||
attrs.hostCatalogId = hostCatalogId;
|
||||
const hostCatalog = hostCatalogs.find(attrs.hostCatalogId);
|
||||
attrs.scopeId = hostCatalog.scope.id;
|
||||
return hosts.create(attrs);
|
||||
});
|
||||
this.get('/scopes/:scope_id/host-catalogs/:hostCatalogId/hosts/:id');
|
||||
this.patch('/scopes/:scope_id/host-catalogs/:hostCatalogId/hosts/:id');
|
||||
this.del('/scopes/:scope_id/host-catalogs/:hostCatalogId/hosts/:id');
|
||||
this.get('/hosts/:id');
|
||||
this.patch('/hosts/:id');
|
||||
this.del('/hosts/:id');
|
||||
|
||||
// host-set
|
||||
|
||||
this.get('/scopes/:scope_id/host-catalogs/:hostCatalogId/host-sets', function ({ hostSets }, { params: { hostCatalogId } }) {
|
||||
this.get('/host-sets', function ({ hostSets }, { queryParams: { host_catalog_id: hostCatalogId } }) {
|
||||
return hostSets.where({ hostCatalogId });
|
||||
});
|
||||
this.post('/scopes/:scope_id/host-catalogs/:hostCatalogId/host-sets', function ({ hostSets }, { params: { hostCatalogId } }) {
|
||||
this.post('/host-sets', function ({ hostCatalogs, hostSets }) {
|
||||
const attrs = this.normalizedRequestAttrs();
|
||||
attrs.hostCatalogId = hostCatalogId;
|
||||
const hostCatalog = hostCatalogs.find(attrs.hostCatalogId);
|
||||
attrs.scopeId = hostCatalog.scope.id;
|
||||
return hostSets.create(attrs);
|
||||
});
|
||||
this.get('/scopes/:scope_id/host-catalogs/:hostCatalogId/host-sets/:id');
|
||||
this.patch('/scopes/:scope_id/host-catalogs/:hostCatalogId/host-sets/:id');
|
||||
this.del('/scopes/:scope_id/host-catalogs/:hostCatalogId/host-sets/:id');
|
||||
this.post('/scopes/:scope_id/host-catalogs/:hostCatalogId/host-sets/:idMethod', function ({ hostSets }, { params: { idMethod } }) {
|
||||
this.get('/host-sets/:id');
|
||||
this.patch('/host-sets/:id');
|
||||
this.del('/host-sets/:id');
|
||||
this.post('/host-sets/:idMethod', function ({ hostSets }, { params: { idMethod } }) {
|
||||
const attrs = this.normalizedRequestAttrs();
|
||||
const id = idMethod.split(':')[0];
|
||||
const method = idMethod.split(':')[1];
|
||||
|
||||
@@ -5,7 +5,7 @@ export default factory.extend({
|
||||
|
||||
withChildren: trait({
|
||||
afterCreate(hostCatalog, server) {
|
||||
const scope = hostCatalog.scope;
|
||||
const { scope } = hostCatalog;
|
||||
const hosts = server.createList('host', 10, { scope, hostCatalog });
|
||||
server.createList('host-set', 3, { scope, hostCatalog, hosts });
|
||||
}
|
||||
|
||||
@@ -13,7 +13,12 @@ export default factory.extend({
|
||||
afterCreate(target, server) {
|
||||
let randomlySelectedHostSets;
|
||||
randomlySelectedHostSets = server.schema.hostSets
|
||||
.where(item => item.scope.id === target.scope.id).models
|
||||
// BLERG: fun fact, for no reason at all, the element passed
|
||||
// into a where function is not a full model instance, as you might
|
||||
// expect at this level of abstraction, but appears to be a serialized
|
||||
// representation of the model instance. It's very confusing since
|
||||
// the result set of `where` _is a collection of model instances_.
|
||||
.where(hostSet => hostSet.scopeId === target.scope.id).models
|
||||
.filter(() => randomBoolean(hostSetChance));
|
||||
target.update({hostSets: randomlySelectedHostSets});
|
||||
}
|
||||
|
||||
@@ -12,6 +12,6 @@ export default Factory.extend({
|
||||
created_time: () => date.recent(),
|
||||
updated_time: () => date.recent(),
|
||||
version: () => random.number(),
|
||||
address: () => internet.ipv6(),
|
||||
attributes: () => { return { address: internet.ipv6() } },
|
||||
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
import { Model, belongsTo } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
|
||||
scope: belongsTo()
|
||||
|
||||
});
|
||||
@@ -2,6 +2,7 @@ import { Model, belongsTo, hasMany } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
|
||||
scope: belongsTo(),
|
||||
target: belongsTo(),
|
||||
hostCatalog: belongsTo(),
|
||||
hosts: hasMany()
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Model, belongsTo } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
|
||||
scope: belongsTo(),
|
||||
hostCatalog: belongsTo()
|
||||
|
||||
});
|
||||
@@ -24,8 +24,7 @@ export default function(server) {
|
||||
|
||||
// Other resources
|
||||
server.schema.scopes.where({type: 'project'}).models.forEach(scope => {
|
||||
const scopePojo = { id: scope.id, type: scope.type };
|
||||
server.createList('host-catalog', 2, { scope: scopePojo }, 'withChildren');
|
||||
server.createList('host-catalog', 2, { scope }, 'withChildren');
|
||||
server.createList('target', 2, { scope }, 'withRandomHostSets');
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
import ApplicationSerializer from './application';
|
||||
import { underscore } from '@ember/string';
|
||||
|
||||
export default ApplicationSerializer.extend({
|
||||
modelName: 'host-catalog'
|
||||
modelName: 'host-catalog',
|
||||
|
||||
keyForRelationshipId(relationshipName) {
|
||||
return `${this._container.inflector.singularize(
|
||||
underscore(relationshipName)
|
||||
)}_id`;
|
||||
},
|
||||
|
||||
_hashForModel(model) {
|
||||
const json = ApplicationSerializer.prototype._hashForModel.apply(this, arguments);
|
||||
json.scope = {
|
||||
id: model.scope.id,
|
||||
type: model.scope.type
|
||||
};
|
||||
return json;
|
||||
}
|
||||
|
||||
});
|
||||
@@ -10,10 +10,20 @@ export default ApplicationSerializer.extend({
|
||||
)}_ids`;
|
||||
},
|
||||
|
||||
keyForRelationshipId(relationshipName) {
|
||||
return `${this._container.inflector.singularize(
|
||||
underscore(relationshipName)
|
||||
)}_id`;
|
||||
},
|
||||
|
||||
_hashForModel(model) {
|
||||
const json = ApplicationSerializer.prototype._hashForModel.apply(this, arguments);
|
||||
json.host_ids = model.hostIds;
|
||||
json.host_catalog_id = model.hostCatalogId;
|
||||
json.scope = {
|
||||
id: model.scope.id,
|
||||
type: model.scope.type
|
||||
};
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
import ApplicationSerializer from './application';
|
||||
import { underscore } from '@ember/string';
|
||||
|
||||
export default ApplicationSerializer.extend({
|
||||
modelName: 'host'
|
||||
modelName: 'host',
|
||||
|
||||
keyForRelationshipId(relationshipName) {
|
||||
return `${this._container.inflector.singularize(
|
||||
underscore(relationshipName)
|
||||
)}_id`;
|
||||
},
|
||||
|
||||
_hashForModel(model) {
|
||||
const json = ApplicationSerializer.prototype._hashForModel.apply(this, arguments);
|
||||
json.scope = {
|
||||
id: model.scope.id,
|
||||
type: model.scope.type
|
||||
};
|
||||
return json;
|
||||
}
|
||||
|
||||
});
|
||||
@@ -45,12 +45,7 @@ module('Acceptance | breadcrumbs', function (hooks) {
|
||||
user = this.server.create('user', { scope: orgScope });
|
||||
role = this.server.create('role', { scope: orgScope });
|
||||
group = this.server.create('group', { scope: orgScope });
|
||||
hostCatalog = this.server.create('host-catalog', {
|
||||
scope: {
|
||||
id: project.id,
|
||||
type: project.type
|
||||
}
|
||||
});
|
||||
hostCatalog = this.server.create('host-catalog', { scope: getProjectScope() });
|
||||
|
||||
projectsURL = `/scopes/${orgScope.id}/projects`;
|
||||
newProjectURL = `${projectsURL}/new`;
|
||||
|
||||
@@ -36,16 +36,13 @@ module('Acceptance | host catalogs', function (hooks) {
|
||||
// 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 }
|
||||
scope: { id: 'global', type: 'global' }
|
||||
});
|
||||
instances.scopes.project = this.server.create('scope', { type: 'project',
|
||||
scope: { id: instances.scopes.org.id, type: instances.scopes.org.type }
|
||||
scope: { id: instances.scopes.org.id, type: 'org' }
|
||||
});
|
||||
instances.hostCatalog = this.server.create('host-catalog', {
|
||||
scope: {
|
||||
id: instances.scopes.project.id,
|
||||
type: instances.scopes.project.type
|
||||
}
|
||||
scope: instances.scopes.project
|
||||
});
|
||||
|
||||
// Generate route URLs for resources
|
||||
@@ -124,7 +121,7 @@ module('Acceptance | host catalogs', function (hooks) {
|
||||
|
||||
test('errors are displayed when save host catalog fails', async function (assert) {
|
||||
assert.expect(1);
|
||||
this.server.patch('/scopes/:scope_id/host-catalogs/:id', () => {
|
||||
this.server.patch('/host-catalogs/:id', () => {
|
||||
return new Response(
|
||||
490,
|
||||
{},
|
||||
@@ -149,7 +146,7 @@ module('Acceptance | host catalogs', function (hooks) {
|
||||
|
||||
test('errors are displayed when delete host catalog fails', async function (assert) {
|
||||
assert.expect(1);
|
||||
this.server.del('/scopes/:scope_id/host-catalogs/:id', () => {
|
||||
this.server.del('/host-catalogs/:id', () => {
|
||||
return new Response(
|
||||
490,
|
||||
{},
|
||||
@@ -173,7 +170,7 @@ module('Acceptance | host catalogs', function (hooks) {
|
||||
|
||||
test('saving a new host catalog with invalid fields displays error messages', async function (assert) {
|
||||
assert.expect(2);
|
||||
this.server.post('/scopes/:scope_id/host-catalogs', () => {
|
||||
this.server.post('/host-catalogs', () => {
|
||||
return new Response(
|
||||
400,
|
||||
{},
|
||||
@@ -211,7 +208,7 @@ module('Acceptance | host catalogs', function (hooks) {
|
||||
|
||||
test('saving an existing host catalog with invalid fields displays error messages', async function (assert) {
|
||||
assert.expect(2);
|
||||
this.server.patch('/scopes/:scope_id/host-catalogs/:id', () => {
|
||||
this.server.patch('/host-catalogs/:id', () => {
|
||||
return new Response(
|
||||
400,
|
||||
{},
|
||||
|
||||
Reference in new issue
Block a user