ui/app/components/new-balancer/component.js

287 lines
7.3 KiB
JavaScript

import Ember from 'ember';
import NewOrEdit from 'ui/mixins/new-or-edit';
import SelectTab from 'ui/mixins/select-tab';
import { debouncedObserver } from 'ui/utils/debounce';
export default Ember.Component.extend(NewOrEdit, SelectTab, {
settings: Ember.inject.service(),
isStandalone: true,
service: null,
existing: null,
balancerConfig: null,
haproxyConfig: null,
allHosts: null,
allServices: null,
allCertificates: null,
listenersArray: null,
targetResources: null,
targetsArray: null,
serviceLinksArray: null,
isGlobal: null,
isRequestedHost: null,
portsAsStrArray: null,
// Errors from components
schedulingErrors: null,
scaleErrors: null,
portErrors: null,
primaryResource: Ember.computed.alias('service'),
launchConfig: Ember.computed.alias('service.launchConfig'),
actions: {
setScale(scale) {
this.set('service.scale', scale);
},
toggleAdvanced() {
this.set('advanced', !this.get('advanced'));
},
setLabels(section,labels) {
this.set(section+'Labels', labels);
},
setGlobal(bool) {
this.set('isGlobal', bool);
},
setListeners(listeners) {
this.set('listenersArray', listeners);
},
setTargets(array, resources) {
this.set('targetsArray', array);
this.set('targetResources', resources);
},
setServiceLinks(links) {
this.set('serviceLinksArray', links);
},
done() {
this.sendAction('done');
},
cancel() {
this.sendAction('cancel');
},
},
didInitAttrs() {
this.labelsChanged();
this.set('listenersArray',[]);
this.set('targetsArray',[]);
this.set('targetResources',[]);
},
didInsertElement() {
this.send('selectTab','ssl');
this.$('INPUT')[0].focus();
},
hasMultipleListeners: function() {
return this.get('listenersArray').filterBy('host').get('length') >= 2;
}.property('listenersArray.@each.host'),
hasHttpListeners: function() {
return this.get('listenersArray').filterBy('protocol','http').get('length') > 0;
}.property('listenersArray.@each.protocol'),
hasSslListeners: function() {
return this.get('listenersArray').filterBy('ssl',true).get('length') > 0;
}.property('listenersArray.@each.ssl'),
listenersChanged: function() {
Ember.run.once(this, 'updateListeners');
}.observes('listenersArray.@each.{host,protocol,container,isPublic,ssl}'),
updateListeners: function() {
var ports = [];
var expose = [];
this.get('listenersArray').forEach(function(listener) {
var hostStr = listener.get('host');
var hostIp, hostPort;
var idx = hostStr.indexOf(':');
if ( idx >= 0 )
{
hostIp = hostStr.substr(0,idx);
hostPort = parseInt(hostStr.substr(idx+1),10);
}
else
{
hostIp = null;
hostPort = parseInt(hostStr,10);
}
var container = parseInt(listener.get('container'),10);
var proto = listener.get('protocol');
// You almost definitely probably want 443->80.
if ( hostPort === 443 && !container && listener.get('ssl'))
{
container = 80;
listener.set('container', 80);
}
if ( hostPort && proto )
{
var str = (hostIp ? hostIp + ':' : '') + hostPort +':'+ (container ? + container : hostPort) + (proto === 'http' ? '': '/' + proto );
if ( listener.get('isPublic') )
{
ports.pushObject(str);
}
else
{
expose.pushObject(str);
}
}
});
this.set('launchConfig.ports', ports.sort().uniq());
this.set('launchConfig.expose', expose.sort().uniq());
},
hasAdvancedSourcePorts: function() {
return this.get('targetsArray').filterBy('isService',true).filter((target) => {
return parseInt(target.get('srcPort'),10) > 0;
}).get('length') > 0;
}.property('targetsArray.@each.{isService,srcPort}'),
hasMultipleTargets: function() {
return this.get('targetsArray').filterBy('value').get('length') >= 2;
}.property('targetsArray.@each.value'),
showAdvancedMatchingWarning: Ember.computed.and('hasAdvancedSourcePorts','hasMultipleListeners','hasMultipleTargets'),
// ----------------------------------
// Labels
// ----------------------------------
userLabels: null,
scaleLabels: null,
schedulingLabels: null,
sslLabels: null,
labelsChanged: debouncedObserver(
'userLabels.@each.{key,value}',
'scaleLabels.@each.{key,value}',
'schedulingLabels.@each.{key,value}',
'sslLabels.@each.{key,value}',
function() {
var out = {};
(this.get('userLabels')||[]).forEach((row) => { out[row.key] = row.value; });
(this.get('scaleLabels')||[]).forEach((row) => { out[row.key] = row.value; });
(this.get('schedulingLabels')||[]).forEach((row) => { out[row.key] = row.value; });
(this.get('sslLabels')||[]).forEach((row) => { out[row.key] = row.value; });
var config = this.get('launchConfig');
if ( config )
{
this.set('launchConfig.labels', out);
}
}
),
// ----------------------------------
// Save
// ----------------------------------
willSave() {
var errors = [];
if ( !this.get('editing') )
{
// Errors from components
errors.pushObjects(this.get('schedulingErrors')||[]);
errors.pushObjects(this.get('scaleErrors')||[]);
if ( errors.length )
{
this.set('errors', errors);
return false;
}
}
return this._super();
},
validate: function() {
var errors = [];
if (!this.get('launchConfig.ports.length') && !this.get('launchConfig.expose.length') )
{
errors.push('Choose one or more ports to listen on');
}
if ( !this.get('targetResources.length') )
{
errors.push('Choose one or more targets to send traffic to');
}
var bad = this.get('targetsArray').filter(function(obj) {
return !Ember.get(obj,'value');
});
if ( bad.get('length') )
{
if ( this.get('isAdvanced') )
{
errors.push('Target Service is required on each Target');
}
else
{
this.get('targetsArray').removeObjects(bad);
}
}
bad = this.get('targetsArray').filter(function(obj) {
return Ember.get(obj, 'srcPort') && !Ember.get(obj, 'hostname') && !Ember.get(obj, 'dstPort') && !Ember.get(obj,'path');
});
if ( bad.get('length') )
{
errors.push('A Target can\'t have just a Source Port. Remove it, or add a Request Host, Request Path, or Target Port.');
}
if ( !this.get('service.defaultCertificateId') )
{
bad = this.get('listenersArray').filterBy('ssl',true);
if ( bad.get('length') )
{
errors.push('Certificate is required with SSL listening ports.');
}
}
if ( errors.length )
{
this.set('errors',errors.uniq());
return false;
}
// Generic validation
this._super();
errors = this.get('errors')||[];
errors.pushObjects(this.get('service').validationErrors());
if ( errors.length )
{
this.set('errors',errors.uniq());
return false;
}
return true;
},
didSave() {
// Set balancer targets
return this.get('service').doAction('setservicelinks', {
serviceLinks: this.get('targetResources'),
});
},
doneSaving() {
this.send('done');
},
});