Add support for editing a load balancer
This adds the row action to the load balancers table to allow editing the load balancer. Partially-Implements: blueprint horizon-lbaas-v2-ui Change-Id: I20b2d4171f2dc06da903036cfb5918986b5f907b
This commit is contained in:
parent
39c2a18699
commit
3c48addc20
|
@ -230,3 +230,17 @@ class LoadBalancer(generic.View):
|
|||
"""
|
||||
lb = neutronclient(request).show_loadbalancer(loadbalancer_id)
|
||||
return lb.get('loadbalancer')
|
||||
|
||||
@rest_utils.ajax()
|
||||
def put(self, request, loadbalancer_id):
|
||||
"""Edit a load balancer.
|
||||
|
||||
"""
|
||||
data = request.DATA
|
||||
spec = {}
|
||||
if data['loadbalancer'].get('name'):
|
||||
spec['name'] = data['loadbalancer']['name']
|
||||
if data['loadbalancer'].get('description'):
|
||||
spec['description'] = data['loadbalancer']['description']
|
||||
return neutronclient(request).update_loadbalancer(
|
||||
loadbalancer_id, {'loadbalancer': spec}).get('loadbalancer')
|
||||
|
|
|
@ -38,8 +38,11 @@ ADD_JS_FILES = [
|
|||
'dashboard/project/lbaasv2/loadbalancers/detail.controller.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/filters.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/actions/batch-actions.service.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/actions/row-actions.service.js',
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/'
|
||||
'wizard.controller.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/edit/'
|
||||
'wizard.controller.js'),
|
||||
'dashboard/project/lbaasv2/workflow/modal.service.js',
|
||||
'dashboard/project/lbaasv2/workflow/model.service.js',
|
||||
'dashboard/project/lbaasv2/workflow/workflow.service.js',
|
||||
|
@ -60,8 +63,12 @@ ADD_JS_SPEC_FILES = [
|
|||
'dashboard/project/lbaasv2/loadbalancers/filters.spec.js',
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/'
|
||||
'batch-actions.service.spec.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/'
|
||||
'row-actions.service.spec.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/'
|
||||
'wizard.controller.spec.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/edit/'
|
||||
'wizard.controller.spec.js'),
|
||||
'dashboard/project/lbaasv2/workflow/modal.service.spec.js',
|
||||
'dashboard/project/lbaasv2/workflow/model.service.spec.js',
|
||||
'dashboard/project/lbaasv2/workflow/workflow.service.spec.js',
|
||||
|
|
|
@ -38,7 +38,8 @@
|
|||
var service = {
|
||||
getLoadBalancers: getLoadBalancers,
|
||||
getLoadBalancer: getLoadBalancer,
|
||||
createLoadBalancer: createLoadBalancer
|
||||
createLoadBalancer: createLoadBalancer,
|
||||
editLoadBalancer: editLoadBalancer
|
||||
};
|
||||
|
||||
return service;
|
||||
|
@ -93,5 +94,21 @@
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.lbaasv2.editLoadBalancer
|
||||
* @description
|
||||
* Edit a load balancer
|
||||
* @param {string} id
|
||||
* @param {object} spec
|
||||
* Specifies the data used to update the load balancer.
|
||||
*/
|
||||
|
||||
function editLoadBalancer(id, spec) {
|
||||
return apiService.put('/api/lbaas/loadbalancers/' + id + '/', spec)
|
||||
.error(function () {
|
||||
toastService.add('error', gettext('Unable to update load balancer.'));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}());
|
||||
|
|
|
@ -60,6 +60,16 @@
|
|||
"testInput": [
|
||||
{ name: 'loadbalancer-1' }
|
||||
]
|
||||
},
|
||||
{
|
||||
"func": "editLoadBalancer",
|
||||
"method": "put",
|
||||
"path": "/api/lbaas/loadbalancers/1234/",
|
||||
"error": "Unable to update load balancer.",
|
||||
"data": { name: 'loadbalancer-1' },
|
||||
"testInput": [
|
||||
'1234', { name: 'loadbalancer-1' }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright 2016 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.loadbalancers')
|
||||
.controller('EditLoadBalancerWizardController', EditLoadBalancerWizardController);
|
||||
|
||||
EditLoadBalancerWizardController.$inject = [
|
||||
'$scope',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.model',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.workflow',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
function EditLoadBalancerWizardController($scope, model, workflowService, gettext) {
|
||||
var scope = $scope;
|
||||
// Note: We set these attributes on the $scope so that the scope inheritance used all through
|
||||
// the wizard continues to work. Using local var to appease eslint angular/ng_controller_as.
|
||||
scope.model = model;
|
||||
scope.submit = scope.model.submit;
|
||||
scope.workflow = workflowService(gettext('Update Load Balancer'),
|
||||
'fa fa-pencil',
|
||||
['loadbalancer']);
|
||||
scope.model.initialize('loadbalancer', scope.launchContext.id);
|
||||
}
|
||||
|
||||
})();
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright 2016 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 Edit Load Balancer Wizard Controller', function() {
|
||||
var ctrl, workflowSpy;
|
||||
var model = {
|
||||
submit: function() {
|
||||
return 'updated';
|
||||
},
|
||||
initialize: angular.noop
|
||||
};
|
||||
var workflow = 'foo';
|
||||
var scope = {
|
||||
launchContext: { id: '1' }
|
||||
};
|
||||
|
||||
beforeEach(module('horizon.framework.util'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
beforeEach(module(function ($provide) {
|
||||
workflowSpy = jasmine.createSpy('workflow').and.returnValue(workflow);
|
||||
$provide.value('horizon.dashboard.project.lbaasv2.workflow.model', model);
|
||||
$provide.value('horizon.dashboard.project.lbaasv2.workflow.workflow', workflowSpy);
|
||||
}));
|
||||
beforeEach(inject(function ($controller) {
|
||||
spyOn(model, 'initialize');
|
||||
ctrl = $controller('EditLoadBalancerWizardController', { $scope: scope });
|
||||
}));
|
||||
|
||||
it('defines the controller', function() {
|
||||
expect(ctrl).toBeDefined();
|
||||
});
|
||||
|
||||
it('calls initialize on the given model', function() {
|
||||
expect(model.initialize).toHaveBeenCalledWith('loadbalancer', '1');
|
||||
});
|
||||
|
||||
it('sets scope.workflow to the given workflow', function() {
|
||||
expect(scope.workflow).toBe(workflow);
|
||||
});
|
||||
|
||||
it('initializes workflow with correct properties', function() {
|
||||
expect(workflowSpy).toHaveBeenCalledWith('Update Load Balancer',
|
||||
'fa fa-pencil', ['loadbalancer']);
|
||||
});
|
||||
|
||||
it('defines scope.submit', function() {
|
||||
expect(scope.submit).toBe(model.submit);
|
||||
expect(scope.submit()).toBe('updated');
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright 2016 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.loadbalancers')
|
||||
.factory('horizon.dashboard.project.lbaasv2.loadbalancers.actions.rowActions',
|
||||
tableRowActions);
|
||||
|
||||
tableRowActions.$inject = [
|
||||
'$q',
|
||||
'$route',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.modal',
|
||||
'horizon.app.core.openstack-service-api.policy',
|
||||
'horizon.framework.util.q.extensions',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @ngname horizon.dashboard.project.lbaasv2.loadbalancers.actions.rowActions
|
||||
*
|
||||
* @description
|
||||
* Provides the service for the Load Balancers table row actions.
|
||||
*
|
||||
* @param $q The angular service for promises.
|
||||
* @param $route The angular $route service.
|
||||
* @param workflowModal The LBaaS workflow modal service.
|
||||
* @param policy The horizon policy service.
|
||||
* @param qExtensions Horizon extensions to the $q service.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
* @returns Load balancers table batch actions service object.
|
||||
*/
|
||||
|
||||
function tableRowActions($q, $route, workflowModal, policy, qExtensions, gettext) {
|
||||
|
||||
var edit = workflowModal.init({
|
||||
controller: 'EditLoadBalancerWizardController',
|
||||
message: gettext('The load balancer has been updated.'),
|
||||
handle: onEdit,
|
||||
allowed: canEdit
|
||||
});
|
||||
|
||||
var service = {
|
||||
actions: actions
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
///////////////
|
||||
|
||||
function actions() {
|
||||
return [{
|
||||
service: edit,
|
||||
template: {
|
||||
text: gettext('Edit')
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
function canEdit(item) {
|
||||
return $q.all([
|
||||
qExtensions.booleanAsPromise(item.provisioning_status === 'ACTIVE'),
|
||||
// This rule is made up and should therefore always pass. At some point there will
|
||||
// likely be a valid rule similar to this that we will want to use.
|
||||
policy.ifAllowed({ rules: [['neutron', 'update_loadbalancer']] })
|
||||
]);
|
||||
}
|
||||
|
||||
function onEdit(/*response*/) {
|
||||
$route.reload();
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright 2016 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 Load Balancers Table Row Actions Service', function() {
|
||||
var rowActionsService, scope, $route, actions, policy;
|
||||
|
||||
function canEdit(item) {
|
||||
spyOn(policy, 'ifAllowed').and.returnValue(true);
|
||||
var promise = actions[0].service.allowed(item);
|
||||
var allowed;
|
||||
promise.then(function() {
|
||||
allowed = true;
|
||||
}, function() {
|
||||
allowed = false;
|
||||
});
|
||||
scope.$apply();
|
||||
expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'update_loadbalancer']]});
|
||||
return allowed;
|
||||
}
|
||||
|
||||
beforeEach(module('horizon.framework.util'));
|
||||
beforeEach(module('horizon.framework.conf'));
|
||||
beforeEach(module('horizon.framework.widgets.toast'));
|
||||
beforeEach(module('horizon.app.core.openstack-service-api'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
beforeEach(module(function($provide) {
|
||||
var response = {
|
||||
data: {
|
||||
id: '1'
|
||||
}
|
||||
};
|
||||
var modal = {
|
||||
open: function() {
|
||||
return {
|
||||
result: {
|
||||
then: function(func) {
|
||||
func(response);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
$provide.value('$modal', modal);
|
||||
}));
|
||||
|
||||
beforeEach(inject(function ($injector) {
|
||||
scope = $injector.get('$rootScope').$new();
|
||||
$route = $injector.get('$route');
|
||||
policy = $injector.get('horizon.app.core.openstack-service-api.policy');
|
||||
rowActionsService = $injector.get(
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.actions.rowActions');
|
||||
actions = rowActionsService.actions();
|
||||
}));
|
||||
|
||||
it('should define correct table row actions', function() {
|
||||
expect(actions.length).toBe(1);
|
||||
expect(actions[0].template.text).toBe('Edit');
|
||||
});
|
||||
|
||||
it('should allow editing an ACTIVE load balancer', function() {
|
||||
expect(canEdit({provisioning_status: 'ACTIVE'})).toBe(true);
|
||||
});
|
||||
|
||||
it('should not allow editing a non-ACTIVE load balancer', function() {
|
||||
expect(canEdit({provisioning_status: 'PENDING_UPDATE'})).toBe(false);
|
||||
});
|
||||
|
||||
it('should have the "allowed" and "perform" functions', function() {
|
||||
actions.forEach(function(action) {
|
||||
expect(action.service.allowed).toBeDefined();
|
||||
expect(action.service.perform).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should reload table after edit', function() {
|
||||
spyOn($route, 'reload').and.callThrough();
|
||||
actions[0].service.perform();
|
||||
expect($route.reload).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
LoadBalancerDetailController.$inject = [
|
||||
'horizon.app.core.openstack-service-api.lbaasv2',
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.actions.rowActions',
|
||||
'$routeParams'
|
||||
];
|
||||
|
||||
|
@ -33,14 +34,16 @@
|
|||
* Controller for the LBaaS v2 load balancers detail page.
|
||||
*
|
||||
* @param api The LBaaS v2 API service.
|
||||
* @param rowActions The load balancer row actions service.
|
||||
* @param $routeParams The angular $routeParams service.
|
||||
* @returns undefined
|
||||
*/
|
||||
|
||||
function LoadBalancerDetailController(api, $routeParams) {
|
||||
function LoadBalancerDetailController(api, rowActions, $routeParams) {
|
||||
|
||||
var ctrl = this;
|
||||
ctrl.loadbalancer = {};
|
||||
ctrl.loadbalancer = null;
|
||||
ctrl.actions = rowActions.actions;
|
||||
|
||||
var loadbalancerId = $routeParams.loadbalancerId;
|
||||
|
||||
|
|
|
@ -29,12 +29,16 @@
|
|||
|
||||
///////////////////////
|
||||
|
||||
beforeEach(module('horizon.framework.util.http'));
|
||||
beforeEach(module('horizon.framework.widgets.toast'));
|
||||
beforeEach(module('horizon.framework.conf'));
|
||||
beforeEach(module('horizon.framework.util'));
|
||||
beforeEach(module('horizon.app.core.openstack-service-api'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
beforeEach(module(function($provide) {
|
||||
$provide.value('$modal', {});
|
||||
}));
|
||||
|
||||
beforeEach(inject(function($injector) {
|
||||
loadbalancer = { id: '1234' };
|
||||
lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
<p ng-if="::ctrl.loadbalancer.description">{$ ::ctrl.loadbalancer.description $}</p>
|
||||
</div>
|
||||
<div class="detail-page">
|
||||
<actions allowed="ctrl.actions" type="row" item="ctrl.loadbalancer"
|
||||
ng-if="ctrl.loadbalancer" class="pull-right"></actions>
|
||||
<div class="detail-statuses">
|
||||
<div>
|
||||
<strong translate>IP Address</strong>
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
|
||||
LoadBalancersTableController.$inject = [
|
||||
'horizon.app.core.openstack-service-api.lbaasv2',
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.actions.batchActions'
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.actions.batchActions',
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.actions.rowActions'
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -34,16 +35,18 @@
|
|||
*
|
||||
* @param api The LBaaS V2 service API.
|
||||
* @param batchActions The load balancer batch actions service.
|
||||
* @param rowActions The load balancer row actions service.
|
||||
* @returns undefined
|
||||
*/
|
||||
|
||||
function LoadBalancersTableController(api, batchActions) {
|
||||
function LoadBalancersTableController(api, batchActions, rowActions) {
|
||||
|
||||
var ctrl = this;
|
||||
ctrl.items = [];
|
||||
ctrl.src = [];
|
||||
ctrl.checked = {};
|
||||
ctrl.batchActions = batchActions;
|
||||
ctrl.rowActions = rowActions;
|
||||
|
||||
init();
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
|
||||
controller = $injector.get('$controller');
|
||||
scope = $injector.get('$rootScope').$new();
|
||||
scope.lbaasv2API = lbaasv2API;
|
||||
spyOn(lbaasv2API, 'getLoadBalancers').and.callFake(fakeAPI);
|
||||
}));
|
||||
|
||||
|
@ -58,6 +57,7 @@
|
|||
expect(ctrl.src).toEqual(items);
|
||||
expect(ctrl.checked).toEqual({});
|
||||
expect(ctrl.batchActions).toBeDefined();
|
||||
expect(ctrl.rowActions).toBeDefined();
|
||||
});
|
||||
|
||||
it('should invoke lbaasv2 apis', function() {
|
||||
|
|
|
@ -77,6 +77,13 @@
|
|||
<td class="rsp-p1">{$ item.provisioning_status | provisioningStatus $}</td>
|
||||
<td class="rsp-p2">{$ item.vip_address $}</td>
|
||||
<td class="rsp-p2">{$ item.listeners.length $}</td>
|
||||
<td class="action-col">
|
||||
<!--
|
||||
Table-row-action-column:
|
||||
Actions taken here apply to a single item/row.
|
||||
-->
|
||||
<actions allowed="table.rowActions.actions" type="row" item="item"></actions>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr ng-repeat-end class="detail-row">
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
<select class="form-control input-sm" name="listener-protocol"
|
||||
id="listener-protocol"
|
||||
ng-options="protocol for protocol in model.listenerProtocols"
|
||||
ng-model="model.spec.listener.protocol" ng-required="model.context.type === 'listener'">
|
||||
ng-model="model.spec.listener.protocol" ng-required="model.context.resource === 'listener'">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -52,7 +52,7 @@
|
|||
<input name="listener-port" id="listener-port"
|
||||
type="number" class="form-control input-sm"
|
||||
ng-model="model.spec.listener.port" ng-pattern="/^\d+$/" min="1" max="65535"
|
||||
ng-required="model.context.type === 'listener'">
|
||||
ng-required="model.context.resource === 'listener'">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@
|
|||
popover-trigger="hover"></span>
|
||||
<input name="loadbalancer-ip" id="loadbalancer-ip"
|
||||
type="text" class="form-control input-sm"
|
||||
ng-model="model.spec.loadbalancer.ip" ng-pattern="::ctrl.ipPattern">
|
||||
ng-model="model.spec.loadbalancer.ip" ng-pattern="::ctrl.ipPattern"
|
||||
ng-disabled="model.context.resource === 'loadbalancer' && model.context.id">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -49,7 +50,8 @@
|
|||
<select class="form-control input-sm" name="loadbalancer-subnet"
|
||||
id="loadbalancer-subnet"
|
||||
ng-options="subnet.name for subnet in model.subnets"
|
||||
ng-model="model.spec.loadbalancer.subnet" ng-required="true">
|
||||
ng-model="model.spec.loadbalancer.subnet" ng-required="true"
|
||||
ng-disabled="model.context.resource === 'loadbalancer' && model.context.id">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -144,56 +144,27 @@
|
|||
} else {
|
||||
model.initializing = true;
|
||||
|
||||
var promises = [];
|
||||
switch ((id ? 'edit' : 'create') + resource) {
|
||||
case 'createloadbalancer':
|
||||
promise = $q.all([
|
||||
lbaasv2API.getLoadBalancers().then(onGetLoadBalancers),
|
||||
neutronAPI.getSubnets().then(onGetSubnets),
|
||||
neutronAPI.getPorts().then(onGetPorts),
|
||||
novaAPI.getServers().then(onGetServers)
|
||||
]).then(initMemberAddresses);
|
||||
model.context.submit = createLoadBalancer;
|
||||
break;
|
||||
case 'editloadbalancer':
|
||||
promise = $q.all([
|
||||
lbaasv2API.getLoadBalancer(model.context.id).then(onGetLoadBalancer),
|
||||
neutronAPI.getSubnets().then(onGetSubnets)
|
||||
]).then(initSubnet);
|
||||
model.context.submit = editLoadBalancer;
|
||||
break;
|
||||
default:
|
||||
throw Error('Invalid resource context: ' + (id ? 'edit' : 'create') + resource);
|
||||
}
|
||||
|
||||
promises.push(lbaasv2API.getLoadBalancers().then(onGetLoadBalancers));
|
||||
promises.push(neutronAPI.getSubnets().then(onGetSubnets));
|
||||
promises.push(neutronAPI.getPorts().then(onGetPorts));
|
||||
promises.push(novaAPI.getServers().then(onGetServers));
|
||||
model.context.submit = createLoadBalancer;
|
||||
|
||||
// // Create load balancer (default)
|
||||
// if (resource === 'loadbalancer' && !id) {
|
||||
// promises.push(lbaasv2API.getLoadBalancers().then(onGetLoadBalancers));
|
||||
// promises.push(neutronAPI.getSubnets().then(onGetSubnets));
|
||||
// promises.push(neutronAPI.getPorts().then(onGetPorts));
|
||||
// promises.push(novaAPI.getServers().then(onGetServers));
|
||||
// model.context.submit = createLoadBalancer;
|
||||
// }
|
||||
// // Edit load balancer
|
||||
// else if (resource === 'loadbalancer' && id) {
|
||||
// // Get load balancer
|
||||
// model.context.submit = editLoadBalancer;
|
||||
// }
|
||||
// // Create listener
|
||||
// else if (resource === 'listener' && !id) {
|
||||
// promises.push(neutronAPI.getSubnets().then(onGetSubnets));
|
||||
// promises.push(neutronAPI.getPorts().then(onGetPorts));
|
||||
// promises.push(novaAPI.getServers().then(onGetServers));
|
||||
// model.context.submit = createListener;
|
||||
// }
|
||||
// // Edit listener
|
||||
// else if (resource === 'listener' && id) {
|
||||
// // Get listener, pool, members, monitor
|
||||
// model.context.submit = editListener;
|
||||
// }
|
||||
// // Edit pool
|
||||
// else if (resource === 'pool' && id) {
|
||||
// // Get pool, members, monitor
|
||||
// model.context.submit = editPool;
|
||||
// }
|
||||
// // Edit monitor
|
||||
// else if (resource === 'monitor' && id) {
|
||||
// // Get monitor
|
||||
// model.context.submit = editMonitor;
|
||||
// }
|
||||
// // Edit members
|
||||
// else if (resource === 'members' && id) {
|
||||
// // Get pool members by pool id
|
||||
// model.context.submit = editMembers;
|
||||
// }
|
||||
|
||||
promise = $q.all(promises);
|
||||
promise.then(onInitSuccess, onInitFail);
|
||||
}
|
||||
|
||||
|
@ -201,7 +172,6 @@
|
|||
}
|
||||
|
||||
function onInitSuccess() {
|
||||
initMemberAddresses();
|
||||
model.initializing = false;
|
||||
model.initialized = true;
|
||||
}
|
||||
|
@ -224,7 +194,25 @@
|
|||
|
||||
function submit() {
|
||||
var finalSpec = angular.copy(model.spec);
|
||||
var resource = model.context.resource;
|
||||
cleanFinalSpecLoadBalancer(finalSpec);
|
||||
cleanFinalSpecListener(finalSpec);
|
||||
cleanFinalSpecPool(finalSpec);
|
||||
cleanFinalSpecMembers(finalSpec);
|
||||
cleanFinalSpecMonitor(finalSpec);
|
||||
removeNulls(finalSpec);
|
||||
return model.context.submit(finalSpec);
|
||||
}
|
||||
|
||||
function createLoadBalancer(spec) {
|
||||
return lbaasv2API.createLoadBalancer(spec);
|
||||
}
|
||||
|
||||
function editLoadBalancer(spec) {
|
||||
return lbaasv2API.editLoadBalancer(model.context.id, spec);
|
||||
}
|
||||
|
||||
function cleanFinalSpecLoadBalancer(finalSpec) {
|
||||
var context = model.context;
|
||||
|
||||
// Load balancer requires subnet
|
||||
if (!finalSpec.loadbalancer.subnet) {
|
||||
|
@ -233,10 +221,23 @@
|
|||
finalSpec.loadbalancer.subnet = finalSpec.loadbalancer.subnet.id;
|
||||
}
|
||||
|
||||
// Cannot edit the subnet
|
||||
if (context.resource === 'loadbalancer' && context.id) {
|
||||
delete finalSpec.subnet;
|
||||
delete finalSpec.ip;
|
||||
}
|
||||
}
|
||||
|
||||
function cleanFinalSpecListener(finalSpec) {
|
||||
|
||||
// Listener requires protocol and port
|
||||
if (!finalSpec.listener.protocol || !finalSpec.listener.port) {
|
||||
delete finalSpec.listener;
|
||||
}
|
||||
}
|
||||
|
||||
function cleanFinalSpecPool(finalSpec) {
|
||||
var resource = model.context.resource;
|
||||
|
||||
// Pool requires protocol and method, and also the listener
|
||||
if (resource !== 'pool' && !finalSpec.listener ||
|
||||
|
@ -244,16 +245,6 @@
|
|||
!finalSpec.pool.method) {
|
||||
delete finalSpec.pool;
|
||||
}
|
||||
|
||||
cleanFinalSpecMembers(finalSpec);
|
||||
cleanFinalSpecMonitor(finalSpec);
|
||||
removeNulls(finalSpec);
|
||||
|
||||
return model.context.submit(finalSpec);
|
||||
}
|
||||
|
||||
function createLoadBalancer(spec) {
|
||||
return lbaasv2API.createLoadBalancer(spec);
|
||||
}
|
||||
|
||||
function cleanFinalSpecMembers(finalSpec) {
|
||||
|
@ -304,7 +295,7 @@
|
|||
|
||||
function onGetLoadBalancers(response) {
|
||||
var existingNames = {};
|
||||
angular.forEach(response.data.items, function(lb) {
|
||||
angular.forEach(response.data.items, function nameExists(lb) {
|
||||
existingNames[lb.name] = 1;
|
||||
});
|
||||
var name;
|
||||
|
@ -324,7 +315,7 @@
|
|||
function onGetServers(response) {
|
||||
model.members.length = 0;
|
||||
var members = [];
|
||||
angular.forEach(response.data.items, function(server) {
|
||||
angular.forEach(response.data.items, function addMember(server) {
|
||||
members.push({
|
||||
id: server.id,
|
||||
name: server.name,
|
||||
|
@ -340,13 +331,13 @@
|
|||
}
|
||||
|
||||
function initMemberAddresses() {
|
||||
angular.forEach(model.members, function(member) {
|
||||
var memberPorts = ports.filter(function(port) {
|
||||
angular.forEach(model.members, function initAddresses(member) {
|
||||
var memberPorts = ports.filter(function filterPortByDevice(port) {
|
||||
return port.device_id === member.id;
|
||||
});
|
||||
member.addresses = [];
|
||||
angular.forEach(memberPorts, function(port) {
|
||||
angular.forEach(port.fixed_ips, function(ip) {
|
||||
angular.forEach(memberPorts, function addAddressesForPort(port) {
|
||||
angular.forEach(port.fixed_ips, function addAddress(ip) {
|
||||
member.addresses.push({
|
||||
ip: ip.ip_address,
|
||||
subnet: ip.subnet_id
|
||||
|
@ -357,6 +348,22 @@
|
|||
});
|
||||
}
|
||||
|
||||
function onGetLoadBalancer(response) {
|
||||
var loadbalancer = response.data;
|
||||
var spec = model.spec.loadbalancer;
|
||||
spec.name = loadbalancer.name || '';
|
||||
spec.description = loadbalancer.description || '';
|
||||
spec.ip = loadbalancer.vip_address || '';
|
||||
spec.subnet = loadbalancer.vip_subnet_id;
|
||||
}
|
||||
|
||||
function initSubnet() {
|
||||
var subnet = model.subnets.filter(function filterSubnetsByLoadBalancer(s) {
|
||||
return s.id === model.spec.loadbalancer.subnet;
|
||||
})[0];
|
||||
model.spec.loadbalancer.subnet = subnet;
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,8 +32,19 @@
|
|||
|
||||
return deferred.promise;
|
||||
},
|
||||
getLoadBalancer: function() {
|
||||
var loadbalancer = { vip_subnet_id: 'subnet-1' };
|
||||
|
||||
var deferred = $q.defer();
|
||||
deferred.resolve({ data: loadbalancer });
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
createLoadBalancer: function(spec) {
|
||||
return spec;
|
||||
},
|
||||
editLoadBalancer: function(id, spec) {
|
||||
return spec;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -190,7 +201,7 @@
|
|||
}));
|
||||
|
||||
beforeEach(function() {
|
||||
model.initialize();
|
||||
model.initialize('loadbalancer');
|
||||
scope.$apply();
|
||||
});
|
||||
|
||||
|
@ -202,11 +213,29 @@
|
|||
});
|
||||
});
|
||||
|
||||
describe('Resource not provided', function() {
|
||||
var initModelNoContext = function() {
|
||||
model.initialize();
|
||||
};
|
||||
|
||||
var initModelNoResource = function() {
|
||||
model.initialize('', 'foo');
|
||||
};
|
||||
|
||||
it('should fail to be initialized - create', function() {
|
||||
expect(initModelNoContext).toThrow(Error('Invalid resource context: createundefined'));
|
||||
});
|
||||
|
||||
it('should fail to be initialized - edit', function() {
|
||||
expect(initModelNoResource).toThrow(Error('Invalid resource context: edit'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('Post initialize model - Initializing', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
model.initializing = true;
|
||||
model.initialize();
|
||||
model.initialize('loadbalancer');
|
||||
scope.$apply();
|
||||
});
|
||||
|
||||
|
@ -297,10 +326,38 @@
|
|||
});
|
||||
});
|
||||
|
||||
describe('Model submit function', function() {
|
||||
describe('context (create loadbalancer)', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
model.initialize();
|
||||
model.initialize('loadbalancer');
|
||||
scope.$apply();
|
||||
});
|
||||
|
||||
it('should initialize context', function() {
|
||||
expect(model.context.resource).toBe('loadbalancer');
|
||||
expect(model.context.id).toBeUndefined();
|
||||
expect(model.context.submit.name).toBe('createLoadBalancer');
|
||||
});
|
||||
});
|
||||
|
||||
describe('context (edit loadbalancer)', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
model.initialize('loadbalancer', '1');
|
||||
scope.$apply();
|
||||
});
|
||||
|
||||
it('should initialize context', function() {
|
||||
expect(model.context.resource).toBe('loadbalancer');
|
||||
expect(model.context.id).toBe('1');
|
||||
expect(model.context.submit.name).toBe('editLoadBalancer');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Model submit function (create loadbalancer)', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
model.initialize('loadbalancer');
|
||||
scope.$apply();
|
||||
});
|
||||
|
||||
|
@ -427,5 +484,24 @@
|
|||
});
|
||||
});
|
||||
|
||||
describe('Model submit function (edit loadbalancer)', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
model.initialize('loadbalancer', '1');
|
||||
scope.$apply();
|
||||
});
|
||||
|
||||
it('should set final spec properties', function() {
|
||||
model.spec.loadbalancer.description = 'new description';
|
||||
|
||||
var finalSpec = model.submit();
|
||||
|
||||
expect(finalSpec.loadbalancer.name).toBe('');
|
||||
expect(finalSpec.loadbalancer.description).toBe('new description');
|
||||
expect(finalSpec.loadbalancer.ip).toBe('');
|
||||
expect(finalSpec.loadbalancer.subnet).toBe('subnet-1');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
|
|
Loading…
Reference in New Issue