From 7b90156da1da5ae292cb288670fa65831d0b06e9 Mon Sep 17 00:00:00 2001 From: Lucas Palm Date: Tue, 5 Jan 2016 11:42:40 -0600 Subject: [PATCH] Add the angular LBaaS V2 members table and detail pages This change implements the members table under the 'Members' tab on the pools detail page that shows all of the members that belong to that particular pool. It also adds the member detail page which includes the details for a specific member in the pool. Partially-Implements: blueprint horizon-lbaas-v2-ui Change-Id: I879c840d174630c697375c5ce7649b01303aeb00 --- neutron_lbaas_dashboard/api/rest/lbaasv2.py | 36 ++++++ .../_1481_project_ng_loadbalancersv2_panel.py | 10 +- .../openstack-service-api/lbaasv2.service.js | 43 ++++++- .../lbaasv2.service.spec.js | 19 +++ .../project/lbaasv2/lbaasv2.module.js | 6 +- .../project/lbaasv2/lbaasv2.module.spec.js | 8 +- .../lbaasv2/members/detail.controller.js | 98 ++++++++++++++++ .../lbaasv2/members/detail.controller.spec.js | 111 ++++++++++++++++++ .../project/lbaasv2/members/detail.html | 39 ++++++ .../project/lbaasv2/members/members.module.js | 31 +++++ .../lbaasv2/members/members.module.spec.js | 25 ++++ .../lbaasv2/members/table.controller.js | 64 ++++++++++ .../lbaasv2/members/table.controller.spec.js | 66 +++++++++++ .../project/lbaasv2/members/table.html | 76 ++++++++++++ .../project/lbaasv2/pools/detail.html | 3 +- 15 files changed, 628 insertions(+), 7 deletions(-) create mode 100644 neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.js create mode 100644 neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.spec.js create mode 100644 neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/detail.html create mode 100644 neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/members.module.js create mode 100644 neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/members.module.spec.js create mode 100644 neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/table.controller.js create mode 100644 neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/table.controller.spec.js create mode 100644 neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/table.html diff --git a/neutron_lbaas_dashboard/api/rest/lbaasv2.py b/neutron_lbaas_dashboard/api/rest/lbaasv2.py index 6181e4a..fa319a1 100644 --- a/neutron_lbaas_dashboard/api/rest/lbaasv2.py +++ b/neutron_lbaas_dashboard/api/rest/lbaasv2.py @@ -310,3 +310,39 @@ class Pool(generic.View): """ lb = neutronclient(request).show_lbaas_pool(pool_id) return lb.get('pool') + + +@urls.register +class Members(generic.View): + """API for load balancer members. + + """ + url_regex = r'lbaas/pools/(?P[^/]+)/members/$' + + @rest_utils.ajax() + def get(self, request, pool_id): + """List of members for the current project. + + The listing result is an object with property "items". + """ + tenant_id = request.user.project_id + result = neutronclient(request).list_lbaas_members(pool_id, + tenant_id=tenant_id) + return {'items': result.get('members')} + + +@urls.register +class Member(generic.View): + """API for retrieving a single member. + + """ + url_regex = r'lbaas/pools/(?P[^/]+)' + \ + '/members/(?P[^/]+)/$' + + @rest_utils.ajax() + def get(self, request, member_id, pool_id): + """Get a specific member belonging to a specific pool. + + """ + lb = neutronclient(request).show_lbaas_member(member_id, pool_id) + return lb.get('member') diff --git a/neutron_lbaas_dashboard/enabled/_1481_project_ng_loadbalancersv2_panel.py b/neutron_lbaas_dashboard/enabled/_1481_project_ng_loadbalancersv2_panel.py index 98cdd60..9a6e6e8 100644 --- a/neutron_lbaas_dashboard/enabled/_1481_project_ng_loadbalancersv2_panel.py +++ b/neutron_lbaas_dashboard/enabled/_1481_project_ng_loadbalancersv2_panel.py @@ -57,7 +57,10 @@ ADD_JS_FILES = [ 'dashboard/project/lbaasv2/listeners/detail.controller.js', 'dashboard/project/lbaasv2/listeners/filters.js', 'dashboard/project/lbaasv2/pools/pools.module.js', - 'dashboard/project/lbaasv2/pools/detail.controller.js' + 'dashboard/project/lbaasv2/pools/detail.controller.js', + 'dashboard/project/lbaasv2/members/members.module.js', + 'dashboard/project/lbaasv2/members/detail.controller.js', + 'dashboard/project/lbaasv2/members/table.controller.js' ] ADD_JS_SPEC_FILES = [ @@ -89,7 +92,10 @@ ADD_JS_SPEC_FILES = [ 'dashboard/project/lbaasv2/listeners/detail.controller.spec.js', 'dashboard/project/lbassv2/listeners/filters.spec.js', 'dashboard/project/lbaasv2/pools/pools.module.spec.js', - 'dashboard/project/lbaasv2/pools/detail.controller.spec.js' + 'dashboard/project/lbaasv2/pools/detail.controller.spec.js', + 'dashboard/project/lbaasv2/members/members.module.spec.js', + 'dashboard/project/lbaasv2/members/detail.controller.spec.js', + 'dashboard/project/lbaasv2/members/table.controller.spec.js' ] ADD_SCSS_FILES = [ diff --git a/neutron_lbaas_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js b/neutron_lbaas_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js index 0f546d9..5cc25cc 100644 --- a/neutron_lbaas_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js +++ b/neutron_lbaas_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js @@ -42,7 +42,9 @@ editLoadBalancer: editLoadBalancer, getListeners: getListeners, getListener: getListener, - getPool: getPool + getPool: getPool, + getMembers: getMembers, + getMember: getMember }; return service; @@ -152,6 +154,8 @@ }); } + // Pools + /** * @name horizon.app.core.openstack-service-api.lbaasv2.getPool * @description @@ -167,5 +171,42 @@ }); } + // Members + + /** + * @name horizon.app.core.openstack-service-api.lbaasv2.getMembers + * @description + * Get a list of members. + * @param {string} poolId + * Specifies the id of the pool the members belong to. + * + * The listing result is an object with property "items". Each item is + * a member. + */ + + function getMembers(poolId) { + return apiService.get('/api/lbaas/pools/' + poolId + '/members/') + .error(function () { + toastService.add('error', gettext('Unable to retrieve members.')); + }); + } + + /** + * @name horizon.app.core.openstack-service-api.lbaasv2.getMember + * @description + * Get a single pool Member by ID. + * @param {string} poolId + * Specifies the id of the pool the member belongs to. + * @param {string} memberId + * Specifies the id of the member to request. + */ + + function getMember(poolId, memberId) { + return apiService.get('/api/lbaas/pools/' + poolId + '/members/' + memberId) + .error(function () { + toastService.add('error', gettext('Unable to retrieve member.')); + }); + } + } }()); diff --git a/neutron_lbaas_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js b/neutron_lbaas_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js index 9b3cee5..5d793f0 100644 --- a/neutron_lbaas_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js +++ b/neutron_lbaas_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js @@ -90,6 +90,25 @@ '1234' ] }, + { + "func": "getMembers", + "method": "get", + "path": "/api/lbaas/pools/1234/members/", + "error": "Unable to retrieve members.", + "testInput": [ + '1234' + ] + }, + { + "func": "getMember", + "method": "get", + "path": "/api/lbaas/pools/1234/members/5678", + "error": "Unable to retrieve member.", + "testInput": [ + '1234', + '5678' + ] + }, { "func": "createLoadBalancer", "method": "post", diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js index 7112c62..250ffbc 100644 --- a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js @@ -28,7 +28,8 @@ 'ngRoute', 'horizon.dashboard.project.lbaasv2.loadbalancers', 'horizon.dashboard.project.lbaasv2.listeners', - 'horizon.dashboard.project.lbaasv2.pools' + 'horizon.dashboard.project.lbaasv2.pools', + 'horizon.dashboard.project.lbaasv2.members' ]) .config(config) .constant('horizon.dashboard.project.lbaasv2.patterns', { @@ -68,6 +69,9 @@ }) .when(href + 'pools/detail/:poolId', { templateUrl: basePath + 'pools/detail.html' + }) + .when(href + 'pools/:poolId/members/detail/:memberId', { + templateUrl: basePath + 'members/detail.html' }); } diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js index 8a6b7ae..0d706eb 100644 --- a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js @@ -120,10 +120,16 @@ { templateUrl: basePath + 'pools/detail.html' } + ], + [ + href + 'pools/:poolId/members/detail/:memberId', + { + templateUrl: basePath + 'members/detail.html' + } ] ]; - expect($routeProvider.when.calls.count()).toBe(4); + expect($routeProvider.when.calls.count()).toBe(5); angular.forEach($routeProvider.when.calls.all(), function(call, i) { expect(call.args).toEqual(routes[i]); }); diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.js b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.js new file mode 100644 index 0000000..301ef54 --- /dev/null +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.js @@ -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'; + + angular + .module('horizon.dashboard.project.lbaasv2.members') + .controller('MemberDetailController', MemberDetailController); + + MemberDetailController.$inject = [ + 'horizon.app.core.openstack-service-api.lbaasv2', + '$routeParams' + ]; + + /** + * @ngdoc controller + * @name MemberDetailController + * + * @description + * Controller for the LBaaS v2 member detail page. + * + * @param api The LBaaS v2 API service. + * @param $routeParams The angular $routeParams service. + * @returns undefined + */ + + function MemberDetailController(api, $routeParams) { + var ctrl = this; + ctrl.member = {}; + ctrl.pool = {}; + ctrl.listener = {}; + ctrl.loadbalancer = {}; + + var poolID = $routeParams.poolId; + var memberID = $routeParams.memberId; + + init(); + + //////////////////////////////// + + function init() { + api.getMember(poolID, memberID).success(memberSuccess); + } + + function memberSuccess(response) { + ctrl.member = response; + getPoolDetails(poolID); + } + + function getPoolDetails(poolId) { + api.getPool(poolId).success(poolSuccess); + } + + function poolSuccess(response) { + ctrl.pool = response; + if (ctrl.pool.hasOwnProperty('listeners') && + ctrl.pool.listeners.length > 0) { + getListenerDetails(ctrl.pool.listeners[0].id); + } + } + + function getListenerDetails(listenerId) { + api.getListener(listenerId).success(listenerSuccess); + } + + function listenerSuccess(response) { + ctrl.listener = response; + + if (ctrl.listener.hasOwnProperty('loadbalancers') && + ctrl.listener.loadbalancers.length > 0) { + getLoadBalancerDetails(ctrl.listener.loadbalancers[0].id); + } + } + + function getLoadBalancerDetails(loadbalancerId) { + api.getLoadBalancer(loadbalancerId).success(loadbalancerSuccess); + } + + function loadbalancerSuccess(response) { + ctrl.loadbalancer = response; + } + + } + +})(); diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.spec.js b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.spec.js new file mode 100644 index 0000000..6f0813f --- /dev/null +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.spec.js @@ -0,0 +1,111 @@ +/* + * 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 Member Detail Controller', function() { + var controller, lbaasv2API, member, pool, listener, loadbalancer; + + function fakeMemberAPI() { + return { + success: function(callback) { + callback(member); + } + }; + } + + function fakePoolAPI() { + return { + success: function(callback) { + callback(pool); + } + }; + } + + function fakeListenerAPI() { + return { + success: function(callback) { + callback(listener); + } + }; + } + + function fakeLoadBalancerAPI() { + return { + success: function(callback) { + callback(loadbalancer); + } + }; + } + + /////////////////////// + + beforeEach(module('horizon.framework.util.http')); + beforeEach(module('horizon.framework.widgets.toast')); + beforeEach(module('horizon.framework.conf')); + beforeEach(module('horizon.app.core.openstack-service-api')); + beforeEach(module('horizon.dashboard.project.lbaasv2')); + + beforeEach(inject(function($injector) { + member = { id: '5678' }; + lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2'); + controller = $injector.get('$controller'); + spyOn(lbaasv2API, 'getMember').and.callFake(fakeMemberAPI); + spyOn(lbaasv2API, 'getPool').and.callFake(fakePoolAPI); + spyOn(lbaasv2API, 'getListener').and.callFake(fakeListenerAPI); + spyOn(lbaasv2API, 'getLoadBalancer').and.callFake(fakeLoadBalancerAPI); + })); + + function createController() { + return controller('MemberDetailController', { + api: lbaasv2API, + $routeParams: { poolId: 'poolId', memberId: 'memberId' } + }); + } + + it('should invoke lbaasv2 apis', function() { + pool = { id: 'poolId', listeners: [{id: 'listenerId'}] }; + listener = { id: 'listenerId', loadbalancers: [{id: 'loadbalancerId'}] }; + loadbalancer = { id: 'loadbalancerId' }; + createController(); + expect(lbaasv2API.getMember).toHaveBeenCalledWith('poolId', 'memberId'); + expect(lbaasv2API.getPool).toHaveBeenCalledWith('poolId'); + expect(lbaasv2API.getListener).toHaveBeenCalledWith('listenerId'); + expect(lbaasv2API.getLoadBalancer).toHaveBeenCalledWith('loadbalancerId'); + }); + + it('should not invoke the getListener or getLoadBalancer lbaasv2 api', function() { + pool = { id: 'poolId', listeners: [] }; + createController(); + expect(lbaasv2API.getMember).toHaveBeenCalledWith('poolId', 'memberId'); + expect(lbaasv2API.getPool).toHaveBeenCalledWith('poolId'); + expect(lbaasv2API.getListener).not.toHaveBeenCalled(); + expect(lbaasv2API.getLoadBalancer).not.toHaveBeenCalled(); + }); + + it('should not invoke getLoadBalancer lbaasv2 api', function() { + pool = { id: 'poolId', listeners: [{id: 'listenerId'}] }; + listener = { id: 'listenerId', loadbalancers: [] }; + createController(); + expect(lbaasv2API.getMember).toHaveBeenCalledWith('poolId', 'memberId'); + expect(lbaasv2API.getPool).toHaveBeenCalledWith('poolId'); + expect(lbaasv2API.getListener).toHaveBeenCalledWith('listenerId'); + expect(lbaasv2API.getLoadBalancer).not.toHaveBeenCalled(); + }); + + }); + +})(); diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/detail.html b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/detail.html new file mode 100644 index 0000000..6736fe1 --- /dev/null +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/detail.html @@ -0,0 +1,39 @@ +
+ +
+
+
+
Member ID
+
{$ ::ctrl.member.id $}
+
+
+
Tenant ID
+
{$ ::ctrl.member.tenant_id $}
+
+
+
Protocol Port
+
{$ ::ctrl.member.protocol_port $}
+
+
+
Admin State Up
+
{$ ::ctrl.member.admin_state_up | yesno $}
+
+
+
Address
+
{$ ::ctrl.member.address $}
+
+
+
Weight
+
{$ ::ctrl.member.weight $}
+
+
+
+
\ No newline at end of file diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/members.module.js b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/members.module.js new file mode 100644 index 0000000..0beeab5 --- /dev/null +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/members.module.js @@ -0,0 +1,31 @@ +/* + * 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'; + + /** + * @ngdoc overview + * @ngname horizon.dashboard.project.lbaasv2.members + * + * @description + * Provides the services and widgets required to support and display the project members + * for the load balancers v2 panel. + */ + + angular + .module('horizon.dashboard.project.lbaasv2.members', []); + +})(); diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/members.module.spec.js b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/members.module.spec.js new file mode 100644 index 0000000..1806d83 --- /dev/null +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/members.module.spec.js @@ -0,0 +1,25 @@ +/* + * 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 Members Module', function() { + it('should exist', function() { + expect(angular.module('horizon.dashboard.project.lbaasv2.members')).toBeDefined(); + }); + }); + +})(); diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/table.controller.js b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/table.controller.js new file mode 100644 index 0000000..7875ad5 --- /dev/null +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/table.controller.js @@ -0,0 +1,64 @@ +/* + * 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.members') + .controller('MembersTableController', MembersTableController); + + MembersTableController.$inject = [ + 'horizon.app.core.openstack-service-api.lbaasv2', + '$routeParams' + ]; + + /** + * @ngdoc controller + * @name MembersTableController + * + * @description + * Controller for the LBaaS v2 members table. Serves as the focal point for table actions. + * + * @param api The LBaaS V2 service API. + * @param $routeParams The angular $routeParams service. + * @returns undefined + */ + + function MembersTableController(api, $routeParams) { + + var ctrl = this; + ctrl.items = []; + ctrl.src = []; + ctrl.checked = {}; + + var poolID = $routeParams.poolId; + ctrl.pool_id = poolID; + + init(); + + //////////////////////////////// + + function init() { + api.getMembers(poolID).success(success); + } + + function success(response) { + ctrl.src = response.items; + } + + } + +})(); diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/table.controller.spec.js b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/table.controller.spec.js new file mode 100644 index 0000000..005b003 --- /dev/null +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/table.controller.spec.js @@ -0,0 +1,66 @@ +/* + * 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 Members Table Controller', function() { + var controller, lbaasv2API, scope; + var items = []; + + function fakeAPI() { + return { + success: function(callback) { + callback({ items: items }); + } + }; + } + + /////////////////////// + + 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) { + lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2'); + controller = $injector.get('$controller'); + spyOn(lbaasv2API, 'getMembers').and.callFake(fakeAPI); + })); + + function createController() { + return controller('MembersTableController', { $scope: scope }); + } + + it('should initialize correctly', function() { + var ctrl = createController(); + expect(ctrl.items).toEqual([]); + expect(ctrl.src).toEqual(items); + expect(ctrl.checked).toEqual({}); + }); + + it('should invoke lbaasv2 apis', function() { + createController(); + expect(lbaasv2API.getMembers).toHaveBeenCalled(); + }); + + }); +})(); diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/table.html b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/table.html new file mode 100644 index 0000000..669de7f --- /dev/null +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/members/table.html @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + IDIP AddressProtocol PortWeight
+ + {$ ::item.id $}{$ ::item.address $}{$ ::item.protocol_port $}{$ ::item.weight $}
\ No newline at end of file diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/pools/detail.html b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/pools/detail.html index 772a390..788a858 100644 --- a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/pools/detail.html +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/pools/detail.html @@ -57,8 +57,7 @@ - - +