ui: Asyncify Service Model Hooks (#9312)

* ui: Add Kind grouping computed properties

* Use new computed properties and move model hooks to async methods
This commit is contained in:
John Cowen 2020-12-02 15:42:18 +00:00 committed by hashicorp-ci
parent 4fbbfdcfa2
commit 9d9e77f417
5 changed files with 108 additions and 100 deletions

View File

@ -38,6 +38,27 @@ export default class ServiceInstance extends Model {
return [...new Set(sources)];
}
@computed('Service.Kind')
get IsProxy() {
return ['connect-proxy', 'mesh-gateway', 'ingress-gateway', 'terminating-gateway'].includes(
this.Service.Kind
);
}
// IsOrigin means that the service can have associated up or down streams,
// this service being the origin point of those streams
@computed('Service.Kind')
get IsOrigin() {
return !['connect-proxy', 'mesh-gateway'].includes(this.Service.Kind);
}
// IsMeshOrigin means that the service can have associated up or downstreams
// that are in the Consul mesh itself
@computed('IsOrigin')
get IsMeshOrigin() {
return this.IsOrigin && !['terminating-gateway'].includes(this.Service.Kind);
}
@computed('ChecksPassing', 'ChecksWarning', 'ChecksCritical')
get Status() {
switch (true) {

View File

@ -1,6 +1,5 @@
import { inject as service } from '@ember/service';
import Route from 'consul-ui/routing/route';
import { hash } from 'rsvp';
export default class IndexRoute extends Route {
@service('data-source/service') data;
@ -20,14 +19,15 @@ export default class IndexRoute extends Route {
},
};
model(params) {
async model(params, transition) {
const nspace = this.modelFor('nspace').nspace.substr(1);
const dc = this.modelFor('dc').dc.Name;
return hash({
nspace: nspace,
dc: dc,
items: this.data.source(uri => uri`/${nspace}/${dc}/services`),
});
const items = await this.data.source(uri => uri`/${nspace}/${dc}/services`);
return {
dc,
nspace,
items,
};
}
setupController(controller, model) {

View File

@ -1,54 +1,46 @@
import { inject as service } from '@ember/service';
import Route from 'consul-ui/routing/route';
import { hash } from 'rsvp';
import { get } from '@ember/object';
export default class InstanceRoute extends Route {
@service('data-source/service')
data;
@service('data-source/service') data;
model(params) {
async model(params, transition) {
const dc = this.modelFor('dc').dc.Name;
const nspace = this.modelFor('nspace').nspace.substr(1) || 'default';
return hash({
dc: dc,
nspace: nspace,
item: this.data.source(
uri => uri`/${nspace}/${dc}/service-instance/${params.id}/${params.node}/${params.name}`
),
}).then(model => {
// this will not be run in a blocking loop, but this is ok as
// its highly unlikely that a service will suddenly change to being a
// connect-proxy or vice versa so leave as is for now
return hash({
...model,
proxyMeta:
// proxies and mesh-gateways can't have proxies themselves so don't even look
['connect-proxy', 'mesh-gateway'].includes(get(model.item, 'Kind'))
? null
: this.data.source(
uri =>
uri`/${nspace}/${dc}/proxy-instance/${params.id}/${params.node}/${params.name}`
),
}).then(model => {
if (typeof get(model, 'proxyMeta.ServiceID') === 'undefined') {
return model;
}
const proxy = {
id: get(model, 'proxyMeta.ServiceID'),
node: get(model, 'proxyMeta.Node'),
name: get(model, 'proxyMeta.ServiceName'),
const item = await this.data.source(
uri => uri`/${nspace}/${dc}/service-instance/${params.id}/${params.node}/${params.name}`
);
let proxyMeta, proxy;
if (get(item, 'IsOrigin')) {
proxyMeta = await this.data.source(
uri => uri`/${nspace}/${dc}/proxy-instance/${params.id}/${params.node}/${params.name}`
);
if (typeof get(proxyMeta, 'ServiceID') !== 'undefined') {
const proxyParams = {
id: get(proxyMeta, 'ServiceID'),
node: get(proxyMeta, 'Node'),
name: get(proxyMeta, 'ServiceName'),
};
return hash({
...model,
// Proxies have identical dc/nspace as their parent instance
// No need to use Proxy's dc/nspace response
proxy: this.data.source(
uri => uri`/${nspace}/${dc}/service-instance/${proxy.id}/${proxy.node}/${proxy.name}`
),
});
});
});
// Proxies have identical dc/nspace as their parent instance
// so no need to use Proxy's dc/nspace response
// the proxy itself is just a normal service model
proxy = await this.data.source(
uri =>
uri`/${nspace}/${dc}/service-instance/${proxyParams.id}/${proxyParams.node}/${proxyParams.name}`
);
}
}
return {
dc,
nspace,
item,
proxyMeta,
proxy,
};
}
setupController(controller, model) {

View File

@ -1,6 +1,5 @@
import { inject as service } from '@ember/service';
import Route from 'consul-ui/routing/route';
import { hash } from 'rsvp';
import { get } from '@ember/object';
import { action, setProperties } from '@ember/object';
@ -24,54 +23,48 @@ export default class ShowRoute extends Route {
this.refresh();
}
model(params, transition) {
async model(params, transition) {
const dc = this.modelFor('dc').dc.Name;
const nspace = this.modelFor('nspace').nspace.substr(1);
return hash({
slug: params.name,
dc: dc,
nspace: nspace,
items: this.data.source(
uri => uri`/${nspace}/${dc}/service-instances/for-service/${params.name}`
),
urls: this.config.get().dashboard_url_templates,
chain: null,
proxies: [],
topology: null,
})
.then(model => {
return ['connect-proxy', 'mesh-gateway', 'ingress-gateway', 'terminating-gateway'].includes(
get(model, 'items.firstObject.Service.Kind')
)
? model
: hash({
...model,
chain: this.data.source(uri => uri`/${nspace}/${dc}/discovery-chain/${params.name}`),
// Whilst `proxies` isn't used anywhere in the show templates
// it provides a relationship of ProxyInstance on the ServiceInstance
// which can respond at a completely different blocking rate to
// the ServiceInstance itself
proxies: this.data.source(
uri => uri`/${nspace}/${dc}/proxies/for-service/${params.name}`
),
});
})
.then(model => {
let kind = get(model, 'items.firstObject.Service.Kind');
const slug = params.name;
let chain = null;
let topology = null;
let proxies = [];
const urls = this.config.get().dashboard_url_templates;
const items = await this.data.source(
uri => uri`/${nspace}/${dc}/service-instances/for-service/${params.name}`
);
const item = get(items, 'firstObject');
if (get(item, 'IsOrigin')) {
chain = await this.data.source(uri => uri`/${nspace}/${dc}/discovery-chain/${params.name}`);
proxies = await this.data.source(
uri => uri`/${nspace}/${dc}/proxies/for-service/${params.name}`
);
if (get(item, 'IsMeshOrigin')) {
let kind = get(item, 'Service.Kind');
if (typeof kind === 'undefined') {
kind = '';
}
return ['mesh-gateway', 'terminating-gateway'].includes(
get(model, 'items.firstObject.Service.Kind')
)
? model
: hash({
...model,
topology: this.data.source(
uri => uri`/${nspace}/${dc}/topology/${params.name}/${kind}`
),
});
});
topology = await this.data.source(
uri => uri`/${nspace}/${dc}/topology/${params.name}/${kind}`
);
}
}
return {
dc,
nspace,
slug,
items,
urls,
chain,
proxies,
topology,
};
}
setupController(controller, model) {

View File

@ -1,6 +1,5 @@
import { inject as service } from '@ember/service';
import Route from 'consul-ui/routing/route';
import { hash } from 'rsvp';
export default class ServicesRoute extends Route {
@service('data-source/service') data;
@ -18,7 +17,7 @@ export default class ServicesRoute extends Route {
},
};
model() {
async model(params, transition) {
const dc = this.modelFor('dc').dc.Name;
const nspace = this.modelFor('nspace').nspace.substr(1);
const parent = this.routeName
@ -26,11 +25,14 @@ export default class ServicesRoute extends Route {
.slice(0, -1)
.join('.');
const name = this.modelFor(parent).slug;
return hash({
dc: dc,
nspace: nspace,
gatewayServices: this.data.source(uri => uri`/${nspace}/${dc}/gateways/for-service/${name}`),
});
const gatewayServices = await this.data.source(
uri => uri`/${nspace}/${dc}/gateways/for-service/${name}`
);
return {
dc,
nspace,
gatewayServices,
};
}
setupController(controller, model) {