Edit loadbalancer config

This commit is contained in:
Vincent Fiduccia 2015-06-09 20:02:29 -07:00
parent cb404a4dfc
commit 2dfe358803
16 changed files with 245 additions and 128 deletions

View File

@ -1,7 +1,8 @@
import Ember from 'ember';
import { addAction } from 'ui/utils/add-view-action';
import SelectTab from 'ui/mixins/select-tab';
export default Ember.View.extend({
export default Ember.View.extend(SelectTab, {
actions: {
addEnvironment: addAction('addEnvironment', '.environment-name'),
addPort: addAction('addPort', '.port-public'),
@ -13,14 +14,6 @@ export default Ember.View.extend({
addDevice: addAction('addDevice', '.device-host'),
addLabel: addAction('addLabel', '.label-key'),
addSchedulingRule: addAction('addSchedulingRule', '.schedule-rule'),
selectTab: function(name) {
this.set('context.tab',name);
this.$('.tab').removeClass('active');
this.$('.tab[data-section="'+name+'"]').addClass('active');
this.$('.section').addClass('hide');
this.$('.section[data-section="'+name+'"]').removeClass('hide');
}
},
didInsertElement: function() {
@ -109,7 +102,7 @@ export default Ember.View.extend({
this.$('.select-cap-drop').multiselect(opts);
},
priviligedDidChange: function() {
privilegedDidChange: function() {
var add = this.$('.select-cap-add');
var drop = this.$('.select-cap-drop');
if ( add && drop )

View File

@ -1,20 +1,13 @@
import Ember from 'ember';
import { addAction } from 'ui/utils/add-view-action';
import SelectTab from 'ui/mixins/select-tab';
export default Ember.View.extend({
export default Ember.View.extend(SelectTab, {
actions: {
addHost: addAction('addHost', '.lb-host'),
addTargetContainer: addAction('addTargetContainer', '.lb-target'),
addTargetIp: addAction('addTargetIp', '.lb-target'),
addListener: addAction('addListener', '.lb-listener-source-port'),
selectTab: function(name) {
this.set('context.tab',name);
this.$('.tab').removeClass('active');
this.$('.tab[data-section="'+name+'"]').addClass('active');
this.$('.section').addClass('hide');
this.$('.section[data-section="'+name+'"]').removeClass('hide');
}
},
didInsertElement: function() {

View File

@ -29,6 +29,12 @@ var LoadBalancerConfigController = Cattle.TransitioningResourceController.extend
sourceContent: this.get('loadBalancers'),
});
}.property('loadBalancers'),
unremovedListeners: function() {
return UnremovedArrayProxy.create({
sourceContent: this.get('listeners'),
});
}.property('listeners'),
});
LoadBalancerConfigController.reopenClass({

View File

@ -1,8 +1,50 @@
import Ember from 'ember';
import Cattle from 'ui/utils/cattle';
import EditLoadBalancerConfig from 'ui/mixins/edit-loadbalancerconfig';
export default Ember.ObjectController.extend(Cattle.NewOrEditMixin, {
export default Ember.ObjectController.extend(Cattle.NewOrEditMixin, EditLoadBalancerConfig, {
editing: true,
primaryResource: Ember.computed.alias('model.config'),
queryParams: ['tab'],
tab: 'listeners',
initFields: function() {
this._super();
this.initListeners();
this.initStickiness();
this.initHealthCheck();
},
didSave: function() {
var orig = this.get('listeners')||[];
var neu = this.get('listenersArray');
var promises = [];
orig.forEach((listener) => {
// Delete removed
if( neu.indexOf(listener) === -1 )
{
promises.push(listener.delete());
}
});
neu.forEach((listener) => {
if ( orig.indexOf(listener) === -1 )
{
promises.push(listener.save());
}
});
return Ember.RSVP.all(promises).then(() => {
var ids = neu.filter((listener) => {
return neu.indexOf(listener) >= 0;
}).map((listener) => {
return listener.get('id');
});
return this.get('config').doAction('setlisteners',{loadBalancerListenerIds: ids});
});
},
doneSaving: function() {
this.send('goToPrevious');

View File

@ -2,12 +2,57 @@ import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.modelFor('loadbalancerconfig');
var store = this.get('store');
var orig = this.modelFor('loadbalancerconfig');
var config = orig.clone();
var listeners = (orig.get('listeners')||[]).filter((listener) => {
return ['removed','purging','purged'].indexOf(listener.get('state')) === -1;
});
var healthCheck = config.get('healthCheck');
if ( !healthCheck )
{
healthCheck = store.createRecord({
type: 'loadBalancerHealthCheck',
interval: 2000,
responseTimeout: 2000,
healthyThreshold: 2,
unhealthyThreshold: 3,
});
config.set('healthCheck', healthCheck);
}
var appCookie = config.get('appCookieStickinessPolicy');
if ( !appCookie )
{
appCookie = store.createRecord({
type: 'loadBalancerAppCookieStickinessPolicy',
mode: 'path_parameters',
requestLearn: true,
timeout: 3600000,
});
}
var lbCookie = config.get('lbCookieStickinessPolicy');
if ( !appCookie )
{
lbCookie = store.createRecord({
type: 'loadBalancerCookieStickinessPolicy'
});
}
return {
listeners: listeners,
config: config,
healthCheck: healthCheck,
appCookie: appCookie,
lbCookie: lbCookie,
};
},
setupController: function(controller, model) {
controller.set('originalModel',model);
controller.set('model', model.clone());
controller.set('model', model);
controller.initFields();
},
@ -15,6 +60,13 @@ export default Ember.Route.extend({
this.render('loadbalancerconfig/edit', {into: 'application', outlet: 'overlay'});
},
resetController: function (controller, isExiting/*, transition*/) {
if (isExiting)
{
controller.set('tab', 'listeners');
}
},
actions: {
cancel: function() {
this.goToPrevious();

View File

@ -7,7 +7,7 @@
<label for="name">Name</label>
</div>
<div class="col-sm-12 col-md-8">
{{input id="name" type="text" value=name classNames="form-control" placeholder="e.g. Website"}}
{{input id="name" type="text" value=primaryResource.name classNames="form-control" placeholder="e.g. Website"}}
</div>
</div>
@ -16,9 +16,11 @@
<label for="description">Description</label>
</div>
<div class="col-sm-12 col-md-8">
{{textarea id="description" value=description classNames="form-control no-resize" rows="5" placeholder="e.g. Balancer for mycompany.com"}}
{{textarea id="description" value=primaryResource.description classNames="form-control no-resize" rows="5" placeholder="e.g. Balancer for mycompany.com"}}
</div>
</div>
</section>
{{partial "loadbalancer/edit-config"}}
{{partial "save-cancel"}}

View File

@ -1,7 +1,11 @@
import Overlay from "ui/overlay/view";
import SelectTab from 'ui/mixins/select-tab';
import { addAction } from 'ui/utils/add-view-action';
export default Overlay.extend({
export default Overlay.extend(SelectTab, {
actions: {
addListener: addAction('addListener', '.lb-listener-source-port'),
overlayClose: function() {
this.get('controller').send('cancel');
},
@ -9,5 +13,10 @@ export default Overlay.extend({
overlayEnter: function() {
this.get('controller').send('save');
},
}
},
didInsertElement: function() {
this.send('selectTab',this.get('context.tab'));
},
});

View File

@ -1,20 +1,13 @@
import Ember from 'ember';
import { addAction } from 'ui/utils/add-view-action';
import SelectTab from 'ui/mixins/select-tab';
export default Ember.View.extend({
export default Ember.View.extend(SelectTab, {
actions: {
addHost: addAction('addHost', '.lb-host'),
addTargetContainer: addAction('addTargetContainer', '.lb-target'),
addTargetIp: addAction('addTargetIp', '.lb-target'),
addListener: addAction('addListener', '.lb-listener-source-port'),
selectTab: function(name) {
this.set('context.tab',name);
this.$('.tab').removeClass('active');
this.$('.tab[data-section="'+name+'"]').addClass('active');
this.$('.section').addClass('hide');
this.$('.section[data-section="'+name+'"]').removeClass('hide');
}
},
didInsertElement: function() {

View File

@ -1,20 +1,13 @@
import Ember from 'ember';
import { addAction } from 'ui/utils/add-view-action';
import SelectTab from 'ui/mixins/select-tab';
export default Ember.View.extend({
export default Ember.View.extend(SelectTab, {
actions: {
addHost: addAction('addHost', '.lb-host'),
addTargetContainer: addAction('addTargetContainer', '.lb-target'),
addTargetIp: addAction('addTargetIp', '.lb-target'),
addListener: addAction('addListener', '.lb-listener-source-port'),
selectTab: function(name) {
this.set('context.tab',name);
this.$('.tab').removeClass('active');
this.$('.tab[data-section="'+name+'"]').addClass('active');
this.$('.section').addClass('hide');
this.$('.section[data-section="'+name+'"]').removeClass('hide');
}
},
didInsertElement: function() {

View File

@ -472,12 +472,12 @@ export default Ember.Mixin.create(Cattle.NewOrEditMixin, EditHealthCheck, EditLa
portsArray: null,
initPorts: function() {
var out = [];
var ports = this.get('instance.ports')||[];
ports.forEach(function(value) {
// Objects, from edit
if ( typeof value === 'object' )
var ports = this.get('ports');
if ( ports )
{
// Objects, from edit
ports.forEach(function(value) {
out.push({
existing: (value.id ? true : false),
obj: value,
@ -485,6 +485,21 @@ export default Ember.Mixin.create(Cattle.NewOrEditMixin, EditHealthCheck, EditLa
private: value.privatePort,
protocol: value.protocol,
});
});
}
else
{
ports = this.get('instance.ports')||[];
ports.forEach(function(value) {
if ( typeof value === 'object' )
{
// Objects, from clone
out.push({
existing: false,
public: value.publicPort,
private: value.privatePort,
protocol: value.protocol,
});
}
else
{
@ -501,6 +516,7 @@ export default Ember.Mixin.create(Cattle.NewOrEditMixin, EditHealthCheck, EditLa
}
}
});
}
this.set('portsArray', out);
},

View File

@ -27,11 +27,12 @@ export default Ember.Mixin.create(EditHealthCheck,{
listenersArray: null,
initListeners: function() {
var store = this.get('store');
var existing = this.get('balancer.loadBalancerListeners');
var out = [];
if ( existing )
var existingService = this.get('balancer.loadBalancerListeners');
var existingRegular = this.get('listeners');
if ( existingService )
{
existing.forEach((listener) => {
existingService.forEach((listener) => {
var neu = listener.cloneForNew();
neu.setProperties({
serviceId: null,
@ -40,6 +41,10 @@ export default Ember.Mixin.create(EditHealthCheck,{
out.push(neu);
});
}
else if ( existingRegular )
{
out.pushObjects(existingRegular);
}
else
{
out.push(store.createRecord({

13
app/mixins/select-tab.js Normal file
View File

@ -0,0 +1,13 @@
import Ember from 'ember';
export default Ember.Mixin.create({
actions: {
selectTab: function(name) {
this.set('context.tab',name);
this.$('.tab').removeClass('active');
this.$('.tab[data-section="'+name+'"]').addClass('active');
this.$('.section').addClass('hide');
this.$('.section[data-section="'+name+'"]').removeClass('hide');
}
}
});

View File

@ -1,18 +1,11 @@
import Ember from 'ember';
import { addAction } from 'ui/utils/add-view-action';
import SelectTab from 'ui/mixins/select-tab';
export default Ember.View.extend({
export default Ember.View.extend(SelectTab, {
actions: {
addTargetService: addAction('addTargetService', '.lb-target'),
addListener: addAction('addListener', '.lb-listener-source-port'),
selectTab: function(name) {
this.set('context.tab',name);
this.$('.tab').removeClass('active');
this.$('.tab[data-section="'+name+'"]').addClass('active');
this.$('.section').addClass('hide');
this.$('.section[data-section="'+name+'"]').removeClass('hide');
}
},
didInsertElement: function() {

View File

@ -25,9 +25,7 @@
{{input class="form-control input-sm port-public" type="number" min="1" max="65535" value=port.public placeholder="e.g. 80"}}
</td>
<td class="text-center">
<div class="form-group">
<p class="form-control-static"><i class="ss-right"></i></p>
</div>
</td>
<td>
<div class="form-control-static text-muted">{{port.private}}</div>

View File

@ -1,7 +1,7 @@
<div class="well section">
<div class="row">
<div class="col-sm-6">
<h4>Listeners ({{listeners.length}})</h4>
<h4>Listeners ({{unremovedListeners.length}})</h4>
</div>
</div>
@ -16,7 +16,7 @@
</tr>
</thead>
<tbody>
{{#each listener in listeners itemController="loadbalancerlistener"}}
{{#each listener in unremovedListeners itemController="loadbalancerlistener"}}
<tr>
<td>
<span {{bind-attr class=":badge :state listener.stateBackground"}}>
@ -82,13 +82,13 @@
<label>Healthy Threshold</label>
</div>
<div class="col-sm-12 col-md-3">
<span class="form-control-static">{{config.healthCheck.healthyThreshold}}ms</span>
<span class="form-control-static">{{config.healthCheck.healthyThreshold}}</span>
</div>
<div class="col-sm-12 col-md-3">
<label>Unhealthy Threshold</label>
</div>
<div class="col-sm-12 col-md-3">
<span class="form-control-static">{{config.healthCheck.unhealthyThreshold}}ms</span>
<span class="form-control-static">{{config.healthCheck.unhealthyThreshold}}</span>
</div>
</div>
</div>

View File

@ -14,6 +14,16 @@
<tbody>
{{#each listener in listenersArray}}
<tr>
{{#if listener.id}}
<td>{{listener.sourcePort}}/{{listener.sourceProtocol}}</td>
<td class="text-center"><i class="ss-right"></i></td>
<td>{{listener.targetPort}}/{{listener.targetProtocol}}</td>
<td>&nbsp;</td>
<td>{{listener.algorithm}}</td>
<td class="text-right">
<button {{action "removeListener" listener}} class="btn-circle-x" type="button" tabindex="-1"></button>
</td>
{{else}}
<td>
<div class="input-group input-group-sm">
{{input type="text" classNames="form-control lb-listener-source-port" min="1" max="65535" step="1" value=listener.sourcePort placeholder="e.g. 80"}}
@ -32,9 +42,7 @@
</div>
</div>
</td>
<td class="text-center"><div class="form-control-static input-sm"><i class="ss-right"></i></div></td>
<td class="text-center"><div class="form-control-static"><i class="ss-right"></i></div></td>
<td>
<div class="input-group input-group-sm">
{{input type="text" classNames="form-control lb-listener-target-port" min="1" max="65535" step="1" value=listener.targetPort placeholder="e.g. 8080"}}
@ -62,7 +70,7 @@
<td>
{{#if model.isService}}
<div class="form-control-static input-sm">Round Robin</div>
<div class="form-control-static">Round Robin</div>
{{else}}
{{view "select"
class="form-control input-sm"
@ -74,6 +82,7 @@
<td class="text-right">
<button {{action "removeListener" listener}} class="btn-circle-x" type="button" tabindex="-1"></button>
</td>
{{/if}}
</tr>
{{/each}}
</tbody>