diff --git a/app/authenticated/route.js b/app/authenticated/route.js
index b24886fb8..dd1d24101 100644
--- a/app/authenticated/route.js
+++ b/app/authenticated/route.js
@@ -347,26 +347,19 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
},
loadBalancerServiceChanged: function(change) {
- var service = change.data.resource;
this._includeChanged('environment', 'services', 'environmentId', change.data.resource);
- service.importLink('consumedservices');
+ },
+
+ dnsServiceChanged: function(change) {
+ this._includeChanged('environment', 'services', 'environmentId', change.data.resource);
+ },
+
+ externalServiceChanged: function(change) {
+ this._includeChanged('environment', 'services', 'environmentId', change.data.resource);
},
serviceChanged: function(change) {
- var service = change.data.resource;
this._includeChanged('environment', 'services', 'environmentId', change.data.resource);
-
- // Remove the service from depenedent services
- if ( ['removed','purged','purging'].indexOf(service.get('state')) >= 0 )
- {
- ['service','loadBalancerService','dnsService','externalService'].forEach((type) => {
- this.get('store').all(type).forEach((otherService) => {
- (otherService.get('consumedservices')||[]).removeObject(service);
- });
- });
- }
-
- service.importLink('consumedservices');
},
},
diff --git a/app/components/service-pod/template.hbs b/app/components/service-pod/template.hbs
index 814d3a04a..32a373da0 100644
--- a/app/components/service-pod/template.hbs
+++ b/app/components/service-pod/template.hbs
@@ -13,11 +13,22 @@
-{{#if (or model.consumedservices.length model.externalIpAddresses.length)}}
+{{#if (or model.consumedServicesWithNames.length model.externalIpAddresses.length)}}
- {{#each item in model.consumedservices itemController="service"}}
-
{{#link-to "service" item.environmentId item.id}} {{item.displayName}}{{/link-to}}
+ {{#each map in model.consumedServicesWithNames}}
+ {{#with map.service as service controller="service"}}
+
+ {{#link-to "service" service.environmentId service.id}}
+
+ {{#if (eq map.name service.displayName)}}
+ {{map.name}}
+ {{else}}
+ {{service.displayName}}{{#if map.name}} (as {{map.name}}){{/if}}
+ {{/if}}
+ {{/link-to}}
+
+ {{/with}}
{{/each}}
{{#if model.externalIpAddresses.length}}
diff --git a/app/dnsservice/model.js b/app/dnsservice/model.js
index 27fb00be8..267346ec8 100644
--- a/app/dnsservice/model.js
+++ b/app/dnsservice/model.js
@@ -1,35 +1,11 @@
-import Cattle from 'ui/utils/cattle';
+import Service from 'ui/service/model';
-var DnsService = Cattle.TransitioningResource.extend({
- type: 'service',
-
- consumedServicesUpdated: 0,
- onConsumedServicesChanged: function() {
- this.incrementProperty('consumedServicesUpdated');
- }.observes('consumedservices.@each.{id,name,state}'),
+var DnsService = Service.extend({
+ type: 'dnsService',
healthState: function() {
return 'healthy';
}.property(),
-
- combinedState: function() {
- var service = this.get('state');
- var health = this.get('healthState');
- if ( ['active','updating-active'].indexOf(service) === -1 )
- {
- // If the service isn't active, return its state
- return service;
- }
-
- if ( health === 'healthy' )
- {
- return service;
- }
- else
- {
- return 'degraded';
- }
- }.property('state', 'healthState'),
});
DnsService.reopenClass({
diff --git a/app/environment/graph/view.js b/app/environment/graph/view.js
index b0b85e90f..18ced379c 100644
--- a/app/environment/graph/view.js
+++ b/app/environment/graph/view.js
@@ -1,6 +1,7 @@
import Ember from 'ember';
import Util from 'ui/utils/util';
import ThrottledResize from 'ui/mixins/throttled-resize';
+import { activeIcon } from 'ui/service/controller';
export default Ember.View.extend(ThrottledResize,{
classNames: ['environment-graph'],
@@ -72,7 +73,7 @@ export default Ember.View.extend(ThrottledResize,{
var color = (service.get('state') === 'active' ? 'green' : (service.get('state') === 'inactive' ? 'red' : 'yellow'));
var instances = service.get('instances.length')||'No';
- var html = '
' +
+ var html = '
' +
'
'+ Util.escapeHtml(service.get('name')) + '
' +
'
' + instances + ' container' + (instances === 1 ? '' : 's') + '
' +
'
' + Util.escapeHtml(Util.ucFirst(service.get('state'))) + '
';
@@ -89,15 +90,24 @@ export default Ember.View.extend(ThrottledResize,{
unremovedServices.forEach(function(service) {
var serviceId = service.get('id');
- (service.get('consumedservices')||[]).map(function(target) {
+ (service.get('consumedServicesWithNames')||[]).map(function(map) {
+ var target = map.get('service');
var targetId = target.get('id');
var color = (target.get('state') === 'active' ? 'green' : (target.get('state') === 'inactive' ? 'red' : 'yellow'));
- g.setEdge(serviceId, targetId, {
+ var edgeOpts = {
arrowhead: 'vee',
lineInterpolate: 'bundle',
class: color,
- });
+ };
+
+ var mapName = map.get('name');
+ if ( mapName && mapName !== target.get('name') )
+ {
+ edgeOpts.label = mapName;
+ }
+
+ g.setEdge(serviceId, targetId, edgeOpts);
var existing = unexpectedEdges.filter(function(edge) {
return edge.v === serviceId && edge.w === targetId;
diff --git a/app/environment/route.js b/app/environment/route.js
index 1527de74a..e74bfd828 100644
--- a/app/environment/route.js
+++ b/app/environment/route.js
@@ -8,9 +8,10 @@ export default Ember.Route.extend({
filter: {
environmentId: env.get('id'),
},
- include: ['consumedservices','instances']
+ include: ['instances']
}).then((services) => {
env.set('services', services||[]);
+ env.set('services.sortProperties', ['name','id']);
return env;
});
});
diff --git a/app/environments/route.js b/app/environments/route.js
index 17806258a..35180b3c9 100644
--- a/app/environments/route.js
+++ b/app/environments/route.js
@@ -3,14 +3,21 @@ import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
var store = this.get('store');
- return store.findAllUnremoved('environment').then((environments) => {
+
+ var promises = [
+ store.findAllUnremoved('environment'),
+ ];
+
+ return Ember.RSVP.all(promises).then((results) => {
+ var environments = results[0];
+
var promises = [];
environments.forEach((env) => {
var promise = store.find('service', null, {
filter: {
environmentId: env.get('id'),
},
- include: ['consumedservices','instances']
+ include: ['instances']
}).then((services) => {
env.set('services', services||[]);
env.set('services.sortProperties', ['name','id']);
diff --git a/app/externalservice/model.js b/app/externalservice/model.js
index 2b320b7db..f7f8f9097 100644
--- a/app/externalservice/model.js
+++ b/app/externalservice/model.js
@@ -1,35 +1,11 @@
-import Cattle from 'ui/utils/cattle';
+import Service from 'ui/service/model';
-var ExternalService = Cattle.TransitioningResource.extend({
- type: 'service',
-
- consumedServicesUpdated: 0,
- onConsumedServicesChanged: function() {
- this.incrementProperty('consumedServicesUpdated');
- }.observes('consumedservices.@each.{id,name,state}'),
+var ExternalService = Service.extend({
+ type: 'externalService',
healthState: function() {
return 'healthy';
}.property(),
-
- combinedState: function() {
- var service = this.get('state');
- var health = this.get('healthState');
- if ( ['active','updating-active'].indexOf(service) === -1 )
- {
- // If the service isn't active, return its state
- return service;
- }
-
- if ( health === 'healthy' )
- {
- return service;
- }
- else
- {
- return 'degraded';
- }
- }.property('state', 'healthState'),
});
ExternalService.reopenClass({
diff --git a/app/mixins/edit-service.js b/app/mixins/edit-service.js
index 210e18772..a6070703a 100644
--- a/app/mixins/edit-service.js
+++ b/app/mixins/edit-service.js
@@ -50,26 +50,27 @@ export default Ember.Mixin.create(EditLabels, {
serviceLinksAsMap: null,
initServiceLinks: function() {
var out = [];
- var links = this.get('service.consumedservices')||[];
+ var links;
+ if ( this.get('service.id') )
+ {
+ // Edit
+ links = this.get('service.consumedServicesWithNames')||[];
+ }
+ else
+ {
+ // New / Clone
+ links = this.get('service.serviceLinks')||[];
+ }
- links.forEach(function(value) {
- // Objects, from edit
- var id;
- if ( typeof value === 'object' )
- {
- id = Ember.get(value,'id');
- if ( id )
- {
- out.push(Ember.Object.create({
- obj: value,
- serviceId: id,
- }));
- }
- }
- else
- {
- out.push(Ember.Object.create({serviceId: value}));
- }
+ links.forEach(function(obj) {
+ var linkName = obj.get('name');
+ var service = obj.get('service');
+
+ out.push(Ember.Object.create({
+ linkName: (linkName === service.get('name') ? '' : linkName),
+ obj: service,
+ serviceId: service.get('id'),
+ }));
});
this.set('serviceLinksArray', out);
diff --git a/app/service/controller.js b/app/service/controller.js
index acc1982cb..f5249a2e4 100644
--- a/app/service/controller.js
+++ b/app/service/controller.js
@@ -114,9 +114,13 @@ var ServiceController = Cattle.TransitioningResourceController.extend(ReadLabels
}.property('type'),
state: Ember.computed.alias('model.combinedState'),
+
+ activeIcon: function() {
+ return activeIcon(this.get('model'));
+ }.property('type'),
});
-function activeIcon(service)
+export function activeIcon(service)
{
var out = 'ss-layergroup';
switch ( service.get('type').toLowerCase() )
diff --git a/app/service/model.js b/app/service/model.js
index 77646e10b..1da3116a4 100644
--- a/app/service/model.js
+++ b/app/service/model.js
@@ -1,13 +1,85 @@
+import Ember from 'ember';
import Cattle from 'ui/utils/cattle';
import C from 'ui/utils/constants';
+var _allMaps;
+var _allServices;
+var _allLbServices;
+var _allExternalServices;
+var _allDnsServices;
+
var Service = Cattle.TransitioningResource.extend({
type: 'service',
+ _allMaps: null,
consumedServicesUpdated: 0,
+ serviceLinks: null, // Used for clone
+ reservedKeys: ['_allMaps','consumedServicesUpdated','serviceLinks'],
+
+ init: function() {
+ this._super();
+
+ // Hack: keep only one copy of all the services and serviceconsumemaps
+ // But you have to load service and serviceconsumemap beforehand somewhere...
+ // Bonus hack: all('services') doesn't include the other kinds of services, so load all those too.
+ if ( !_allMaps )
+ {
+ _allMaps = this.get('store').allUnremoved('serviceconsumemap');
+ }
+
+ this.set('_allMaps', _allMaps);
+
+ if ( !_allServices )
+ {
+ _allServices = this.get('store').allUnremoved('service');
+ }
+
+ if ( !_allLbServices )
+ {
+ _allLbServices = this.get('store').allUnremoved('loadbalancerservice');
+ }
+
+ if ( !_allExternalServices )
+ {
+ _allExternalServices = this.get('store').allUnremoved('externalservice');
+ }
+
+ if ( !_allDnsServices )
+ {
+ _allDnsServices = this.get('store').allUnremoved('dnsservice');
+ }
+ },
+
+ consumedServicesWithNames: function() {
+ var all = [_allServices, _allLbServices, _allExternalServices, _allDnsServices];
+
+ return this.get('_allMaps').filterProperty('serviceId', this.get('id')).map((map) => {
+ var i = 0;
+ var service = null;
+ while ( i < all.length && !service )
+ {
+ service = all[i].filterProperty('id', map.get('consumedServiceId'))[0];
+ i++;
+ }
+
+ return Ember.Object.create({
+ name: map.get('name'),
+ service: service
+ });
+ }).filter((obj) => {
+ return obj.get('service.id');
+ });
+ }.property('id','_allMaps.@each.{name,serviceId,consumedServiceId}'),
+
+ consumedServices: function() {
+ return this.get('consumedServicesWithNames').map((obj) => {
+ return obj.get('service');
+ });
+ }.property('consumedServicesWithNames.@each.service'),
+
onConsumedServicesChanged: function() {
this.incrementProperty('consumedServicesUpdated');
- }.observes('consumedservices.@each.{id,name,state}'),
+ }.observes('consumedServicesWithNames.@each.{name,service}'),
healthState: function() {
var isGlobal = Object.keys(this.get('labels')||{}).indexOf(C.LABEL.SCHED_GLOBAL) >= 0;
diff --git a/app/service/new-alias/controller.js b/app/service/new-alias/controller.js
index c1563e302..722cecf1d 100644
--- a/app/service/new-alias/controller.js
+++ b/app/service/new-alias/controller.js
@@ -34,7 +34,7 @@ export default Ember.ObjectController.extend(Cattle.NewOrEditMixin, {
targetsArray: null,
initTargets: function() {
- var existing = this.get('dns.consumedservices');
+ var existing = this.get('dns.consumedServices');
var out = [];
if ( existing )
{
diff --git a/app/service/new-alias/route.js b/app/service/new-alias/route.js
index 8e29bff41..25fdb907d 100644
--- a/app/service/new-alias/route.js
+++ b/app/service/new-alias/route.js
@@ -13,7 +13,7 @@ export default Ember.Route.extend({
if ( params.serviceId )
{
- dependencies.pushObject(store.find('service', params.serviceId, {include: ['consumedservices']}));
+ dependencies.pushObject(store.find('service', params.serviceId));
}
return Ember.RSVP.all(dependencies, 'Load dependencies').then(function(results) {
diff --git a/app/service/new-balancer/controller.js b/app/service/new-balancer/controller.js
index 767cfe150..cb51cc51f 100644
--- a/app/service/new-balancer/controller.js
+++ b/app/service/new-balancer/controller.js
@@ -45,7 +45,7 @@ export default Ember.ObjectController.extend(Cattle.NewOrEditMixin, EditLoadBala
targetsArray: null,
initTargets: function() {
- var existing = this.get('balancer.consumedservices');
+ var existing = this.get('balancer.consumedServices');
var out = [];
if ( existing )
{
diff --git a/app/service/new-balancer/route.js b/app/service/new-balancer/route.js
index 83b29fad2..a8ceee4f3 100644
--- a/app/service/new-balancer/route.js
+++ b/app/service/new-balancer/route.js
@@ -13,7 +13,7 @@ export default Ember.Route.extend({
if ( params.serviceId )
{
- dependencies.pushObject(store.find('service', params.serviceId, {include: ['loadbalancerlisteners','consumedservices']}));
+ dependencies.pushObject(store.find('service', params.serviceId, {include: ['loadbalancerlisteners']}));
}
return Ember.RSVP.all(dependencies, 'Load dependencies').then(function(results) {
diff --git a/app/service/new/route.js b/app/service/new/route.js
index deab83da0..468405161 100644
--- a/app/service/new/route.js
+++ b/app/service/new/route.js
@@ -30,6 +30,7 @@ export default Ember.Route.extend({
var allHosts = results[0];
var environment = results[1];
var serviceOrContainer = results[2];
+ var serviceLinks = [];
var instanceData, serviceData, healthCheckData;
if ( serviceOrContainer )
@@ -37,6 +38,7 @@ export default Ember.Route.extend({
if ( serviceOrContainer.get('type') === 'service' )
{
serviceData = serviceOrContainer.serializeForNew();
+ serviceLinks = serviceOrContainer.get('consumedServicesWithNames');
instanceData = serviceData.launchConfig;
delete serviceData.launchConfig;
delete serviceData.instances;
@@ -80,7 +82,10 @@ export default Ember.Route.extend({
}
var instance = this.get('store').createRecord(instanceData);
+
var service = store.createRecord(serviceData);
+ service.set('serviceLinks', serviceLinks);
+
var healthCheck = store.createRecord(healthCheckData);
instance.set('healthCheck', healthCheck);
service.set('launchConfig', instance); // Creating a service needs the isntance definition here
diff --git a/app/serviceconsumemap/model.js b/app/serviceconsumemap/model.js
new file mode 100644
index 000000000..eab77c498
--- /dev/null
+++ b/app/serviceconsumemap/model.js
@@ -0,0 +1,10 @@
+import Cattle from 'ui/utils/cattle';
+
+var ServiceConsumeMap = Cattle.TransitioningResource.extend({
+ type: 'serviceConsumeMap',
+});
+
+ServiceConsumeMap.reopenClass({
+});
+
+export default ServiceConsumeMap;
diff --git a/app/services/route.js b/app/services/route.js
new file mode 100644
index 000000000..215e9f9ca
--- /dev/null
+++ b/app/services/route.js
@@ -0,0 +1,12 @@
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+ model: function() {
+ var store = this.get('store');
+ return Ember.RSVP.all([
+ store.findAllUnremoved('environment'),
+ store.findAllUnremoved('service'),
+ store.findAllUnremoved('serviceconsumemap'),
+ ]);
+ }
+});
diff --git a/config/environment.js b/config/environment.js
index a5b6b6d54..5ff48d1da 100644
--- a/config/environment.js
+++ b/config/environment.js
@@ -49,7 +49,6 @@ module.exports = function(environment) {
'&include=loadBalancerTargets' +
'&include=loadBalancerListeners' +
'&include=instanceLinks' +
- '&include=consumedservices' +
'&include=ipAddresses',
baseAssets: '',
},
diff --git a/package.json b/package.json
index ac5e40d45..5a3a81e3a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "ui",
- "version": "0.25.0",
+ "version": "0.26.0",
"private": true,
"directories": {
"doc": "doc",