diff --git a/octavia_dashboard/api/rest/lbaasv2.py b/octavia_dashboard/api/rest/lbaasv2.py
index 303337e0..223cebec 100644
--- a/octavia_dashboard/api/rest/lbaasv2.py
+++ b/octavia_dashboard/api/rest/lbaasv2.py
@@ -204,6 +204,7 @@ def create_pool(request, **kwargs):
lb_algorithm=data['pool']['method'],
session_persistence=session_persistence,
listener_id=kwargs['listener_id'],
+ loadbalancer_id=kwargs['loadbalancer_id'],
name=data['pool'].get('name'),
description=data['pool'].get('description'),
admin_state_up=data['pool'].get('admin_state_up')
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/delete/delete.action.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/delete/delete.action.service.js
index b3522cd1..fca82d61 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/delete/delete.action.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/delete/delete.action.service.js
@@ -121,9 +121,15 @@
});
if (actionResult.result.failed.length === 0 && actionResult.result.deleted.length > 0) {
- var path = 'project/load_balancer/' + loadbalancerId +
- '/listeners/' + listenerId +
- '/pools/' + poolId;
+ var path;
+ if (listenerId) {
+ path = 'project/load_balancer/' + loadbalancerId +
+ '/listeners/' + listenerId +
+ '/pools/' + poolId;
+ } else {
+ path = 'project/load_balancer/' + loadbalancerId +
+ '/pools/' + poolId;
+ }
$location.path(path);
}
return actionResult.result;
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/delete/delete.action.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/delete/delete.action.service.spec.js
index 1e2d3613..3e44c314 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/delete/delete.action.service.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/delete/delete.action.service.spec.js
@@ -64,7 +64,7 @@
});
});
- it('should handle the action result properly', function() {
+ it('should handle the action result properly with listener', function() {
spyOn($location, 'path');
spyOn(deleteModalService, 'open').and.returnValue({then: angular.noop});
spyOn(lbaasv2API, 'deleteHealthMonitor').and.callFake(angular.noop);
@@ -91,6 +91,33 @@
expect(result.failed[0].id).toBe(1);
});
+ it('should handle the action result properly without listener', function() {
+ spyOn($location, 'path');
+ spyOn(deleteModalService, 'open').and.returnValue({then: angular.noop});
+ spyOn(lbaasv2API, 'deleteHealthMonitor').and.callFake(angular.noop);
+ service.perform({loadbalancerId: 1, poolId: 3, id: 1, name: 'one'});
+ var result = service.deleteResult({
+ fail: [],
+ pass: [{
+ context: {
+ id: 1
+ }
+ }]
+ });
+ var path = 'project/load_balancer/1/pools/3';
+ expect($location.path).toHaveBeenCalledWith(path);
+ expect(result.deleted[0].id).toBe(1);
+ result = service.deleteResult({
+ pass: [],
+ fail: [{
+ context: {
+ id: 1
+ }
+ }]
+ });
+ expect(result.failed[0].id).toBe(1);
+ });
+
describe('allow method', function() {
it('should use default policy if batch action', function () {
spyOn(policyAPI, 'ifAllowed');
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.js
index d0ecd718..fcfb27ee 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.js
@@ -63,6 +63,13 @@
ctrl.provisioningStatus = loadBalancersService.provisioningStatus;
ctrl.loadbalancer = loadbalancer;
ctrl.listener = listener;
+ if (!angular.equals({}, ctrl.listener)) {
+ ctrl.withListenerStyle = {};
+ ctrl.withoutListenerStyle = {display: 'none'};
+ } else {
+ ctrl.withListenerStyle = {display: 'none'};
+ ctrl.withoutListenerStyle = {};
+ }
ctrl.pool = pool;
ctrl.healthmonitor = healthmonitor;
ctrl.resourceType = typeRegistry.getResourceType(resourceType);
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.spec.js
index 6c10c5b5..f9237fc1 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.spec.js
@@ -47,6 +47,19 @@
};
$timeout = _$timeout_;
scope = $rootScope.$new();
+ ctrl = $controller('HealthMonitorDetailController', {
+ $scope: scope,
+ loadbalancer: { id: '123' },
+ listener: {},
+ pool: { id: '123' },
+ healthmonitor: { id: '123' },
+ 'horizon.framework.conf.resource-type-registry.service': service,
+ 'horizon.framework.util.actions.action-result.service': actionResultService,
+ 'horizon.framework.widgets.modal-wait-spinner.service': {
+ showModalSpinner: angular.noop,
+ hideModalSpinner: angular.noop
+ }
+ });
ctrl = $controller('HealthMonitorDetailController', {
$scope: scope,
loadbalancer: { id: '123' },
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.html
index 126018bd..cd741cab 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.html
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.html
@@ -4,8 +4,9 @@
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js b/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js
index 83de477c..f1f8d482 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js
@@ -68,9 +68,12 @@
var loadbalancers = '/project/load_balancer';
var listener = loadbalancers + '/:loadbalancerId/listeners/:listenerId';
- var pool = listener + '/pools/:poolId';
- var member = pool + '/members/:memberId';
- var healthmonitor = pool + '/healthmonitors/:healthmonitorId';
+ var listenerPool = listener + '/pools/:poolId';
+ var listenerPoolMember = listenerPool + '/members/:memberId';
+ var listenerPoolHealthmonitor = listenerPool + '/healthmonitors/:healthmonitorId';
+ var loadbalancerPool = loadbalancers + '/:loadbalancerId/pools/:poolId';
+ var loadbalancerPoolMember = loadbalancerPool + '/members/:memberId';
+ var loadbalancerPoolHealthmonitor = loadbalancerPool + '/healthmonitors/:healthmonitorId';
$routeProvider
.when(loadbalancers, {
@@ -126,7 +129,7 @@
controller: 'ListenerDetailController',
controllerAs: 'ctrl'
})
- .when(pool, {
+ .when(listenerPool, {
templateUrl: basePath + 'pools/details/detail.html',
resolve: {
loadbalancer: [
@@ -169,7 +172,7 @@
controller: 'PoolDetailController',
controllerAs: 'ctrl'
})
- .when(member, {
+ .when(listenerPoolMember, {
templateUrl: basePath + 'members/details/detail.html',
resolve: {
loadbalancer: [
@@ -225,7 +228,7 @@
controller: 'MemberDetailController',
controllerAs: 'ctrl'
})
- .when(healthmonitor, {
+ .when(listenerPoolHealthmonitor, {
templateUrl: basePath + 'healthmonitors/details/detail.html',
resolve: {
loadbalancer: [
@@ -280,6 +283,137 @@
},
controller: 'HealthMonitorDetailController',
controllerAs: 'ctrl'
+ })
+ .when(loadbalancerPool, {
+ templateUrl: basePath + 'pools/details/detail.html',
+ resolve: {
+ loadbalancer: [
+ '$route',
+ 'horizon.app.core.openstack-service-api.lbaasv2',
+ function($route, api) {
+ return api.getLoadBalancer($route.current.params.loadbalancerId, true).then(
+ function success(response) {
+ response.data.floating_ip_address = response.data.floating_ip.ip;
+ return response.data;
+ }
+ );
+ }
+ ],
+ listener: function() {
+ return {};
+ },
+ pool: [
+ '$route',
+ 'horizon.app.core.openstack-service-api.lbaasv2',
+ function($route, api) {
+ return api.getPool($route.current.params.poolId).then(
+ function success(response) {
+ response.data.loadbalancerId = $route.current.params.loadbalancerId;
+ response.data.listenerId = $route.current.params.listenerId;
+ return response.data;
+ }
+ );
+ }
+ ]
+ },
+ controller: 'PoolDetailController',
+ controllerAs: 'ctrl'
+ })
+ .when(loadbalancerPoolMember, {
+ templateUrl: basePath + 'members/details/detail.html',
+ resolve: {
+ loadbalancer: [
+ '$route',
+ 'horizon.app.core.openstack-service-api.lbaasv2',
+ function($route, api) {
+ return api.getLoadBalancer($route.current.params.loadbalancerId, true).then(
+ function success(response) {
+ response.data.floating_ip_address = response.data.floating_ip.ip;
+ return response.data;
+ }
+ );
+ }
+ ],
+ listener: function() {
+ return {};
+ },
+ pool: [
+ '$route',
+ 'horizon.app.core.openstack-service-api.lbaasv2',
+ function($route, api) {
+ return api.getPool($route.current.params.poolId).then(
+ function success(response) {
+ return response.data;
+ }
+ );
+ }
+ ],
+ member: [
+ '$route',
+ 'horizon.app.core.openstack-service-api.lbaasv2',
+ function($route, api) {
+ return api.getMember($route.current.params.poolId,
+ $route.current.params.memberId).then(
+ function success(response) {
+ response.data.loadbalancerId = $route.current.params.loadbalancerId;
+ response.data.listenerId = $route.current.params.listenerId;
+ response.data.poolId = $route.current.params.poolId;
+ return response.data;
+ }
+ );
+ }
+ ]
+ },
+ controller: 'MemberDetailController',
+ controllerAs: 'ctrl'
+ })
+ .when(loadbalancerPoolHealthmonitor, {
+ templateUrl: basePath + 'healthmonitors/details/detail.html',
+ resolve: {
+ loadbalancer: [
+ '$route',
+ 'horizon.app.core.openstack-service-api.lbaasv2',
+ function($route, api) {
+ return api.getLoadBalancer($route.current.params.loadbalancerId, true).then(
+ function success(response) {
+ response.data.floating_ip_address = response.data.floating_ip.ip;
+ return response.data;
+ }
+ );
+ }
+ ],
+ listener: function() {
+ return {};
+ },
+ pool: [
+ '$route',
+ 'horizon.app.core.openstack-service-api.lbaasv2',
+ function($route, api) {
+ return api.getPool($route.current.params.poolId).then(
+ function success(response) {
+ return response.data;
+ }
+ );
+ }
+ ],
+ healthmonitor: [
+ '$route',
+ 'horizon.app.core.openstack-service-api.lbaasv2',
+ function($route, api) {
+ return api.getHealthMonitor(
+ $route.current.params.healthmonitorId).then(
+ function success(response) {
+ response.data.loadbalancerId = $route.current.params.loadbalancerId;
+ response.data.listenerId = $route.current.params.listenerId;
+ response.data.poolId = $route.current.params.poolId;
+ return response.data;
+ }
+ );
+ }
+ ]
+ },
+ controller: 'HealthMonitorDetailController',
+ controllerAs: 'ctrl'
});
}
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js
index 86f8149a..174ec00c 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js
@@ -182,7 +182,7 @@
});
}));
- it('should route resolved pool detail', inject(function($injector) {
+ it('should route resolved listener pool detail', inject(function($injector) {
function loadbalancerAPI() {
var loadbalancer = { provisioning_status: 'ACTIVE' };
return {
@@ -233,7 +233,7 @@
});
}));
- it('should route resolved member detail', inject(function($injector) {
+ it('should route resolved listener pool member detail', inject(function($injector) {
function loadbalancerAPI() {
var loadbalancer = { provisioning_status: 'ACTIVE' };
return {
@@ -297,7 +297,7 @@
});
}));
- it('should route resolved health monitor detail', inject(function($injector) {
+ it('should route resolved listener pool health monitor detail', inject(function($injector) {
function loadbalancerAPI() {
var loadbalancer = { provisioning_status: 'ACTIVE' };
return {
@@ -361,6 +361,146 @@
});
}));
+ it('should route resolved loadbalancer pool detail', inject(function($injector) {
+ function loadbalancerAPI() {
+ var loadbalancer = { provisioning_status: 'ACTIVE' };
+ return {
+ success: function(callback) {
+ callback(loadbalancer);
+ },
+ then: function(callback) {
+ callback({ data: { id: 1, floating_ip: {}}});
+ }
+ };
+ }
+
+ function poolAPI() {
+ var pool = { provisioning_status: 'ACTIVE' };
+ return {
+ success: function(callback) {
+ callback(pool);
+ },
+ then: function(callback) {
+ callback({ data: { id: 1}});
+ }
+ };
+ }
+
+ var lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
+ spyOn(lbaasv2API, 'getLoadBalancer').and.callFake(loadbalancerAPI);
+ spyOn(lbaasv2API, 'getPool').and.callFake(poolAPI);
+ inject(function($route, $location, $rootScope, $httpBackend) {
+ $httpBackend.expectGET(
+ '/static/dashboard/project/lbaasv2/pools/details/detail.html'
+ ).respond({});
+ $location.path('/project/load_balancer/1/pools/3');
+ $rootScope.$digest();
+ expect($route.current).toBeDefined();
+ });
+ }));
+
+ it('should route resolved loadbalancer pool member detail', inject(function($injector) {
+ function loadbalancerAPI() {
+ var loadbalancer = { provisioning_status: 'ACTIVE' };
+ return {
+ success: function(callback) {
+ callback(loadbalancer);
+ },
+ then: function(callback) {
+ callback({ data: { id: 1, floating_ip: {}}});
+ }
+ };
+ }
+
+ function poolAPI() {
+ var pool = { provisioning_status: 'ACTIVE' };
+ return {
+ success: function(callback) {
+ callback(pool);
+ },
+ then: function(callback) {
+ callback({ data: { id: 1}});
+ }
+ };
+ }
+
+ function memberAPI() {
+ var member = { provisioning_status: 'ACTIVE' };
+ return {
+ success: function(callback) {
+ callback(member);
+ },
+ then: function(callback) {
+ callback({ data: { id: 1}});
+ }
+ };
+ }
+
+ var lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
+ spyOn(lbaasv2API, 'getLoadBalancer').and.callFake(loadbalancerAPI);
+ spyOn(lbaasv2API, 'getPool').and.callFake(poolAPI);
+ spyOn(lbaasv2API, 'getMember').and.callFake(memberAPI);
+ inject(function($route, $location, $rootScope, $httpBackend) {
+ $httpBackend.expectGET(
+ '/static/dashboard/project/lbaasv2/members/details/detail.html'
+ ).respond({});
+ $location.path('/project/load_balancer/1/pools/3/members/4');
+ $rootScope.$digest();
+ expect($route.current).toBeDefined();
+ });
+ }));
+
+ it('should route resolved loadbalancer pool health monitor detail', inject(function($injector) {
+ function loadbalancerAPI() {
+ var loadbalancer = { provisioning_status: 'ACTIVE' };
+ return {
+ success: function(callback) {
+ callback(loadbalancer);
+ },
+ then: function(callback) {
+ callback({ data: { id: 1, floating_ip: {}}});
+ }
+ };
+ }
+
+ function poolAPI() {
+ var pool = { provisioning_status: 'ACTIVE' };
+ return {
+ success: function(callback) {
+ callback(pool);
+ },
+ then: function(callback) {
+ callback({ data: { id: 1}});
+ }
+ };
+ }
+
+ function healthmonitorAPI() {
+ var healthmonitor = { provisioning_status: 'ACTIVE' };
+ return {
+ success: function(callback) {
+ callback(healthmonitor);
+ },
+ then: function(callback) {
+ callback({ data: { id: 1}});
+ }
+ };
+ }
+
+ var lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
+ spyOn(lbaasv2API, 'getLoadBalancer').and.callFake(loadbalancerAPI);
+ spyOn(lbaasv2API, 'getPool').and.callFake(poolAPI);
+ spyOn(lbaasv2API, 'getHealthMonitor').and.callFake(healthmonitorAPI);
+ inject(function($route, $location, $rootScope, $httpBackend) {
+ $httpBackend.expectGET(
+ '/static/dashboard/project/lbaasv2/healthmonitors/details/detail.html'
+ ).respond({});
+ $location.path('/project/load_balancer/1/pools/3/healthmonitors/4');
+ $rootScope.$digest();
+ expect($route.current).toBeDefined();
+ });
+ }));
+
it('should redirect to project home on route change error',
inject(function($location, $rootScope) {
spyOn($location, 'path').and.callThrough();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.html
index ac48cfb6..41ed0001 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.html
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.html
@@ -57,12 +57,10 @@
list-function-extra-params="ctrl.listFunctionExtraParams">
-
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.service.js
index a2ec60d6..54fdf3db 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.service.js
@@ -104,10 +104,16 @@
}
function getMemberDetailsPath(item) {
- return 'project/load_balancer/' + item.loadbalancerId +
- '/listeners/' + item.listenerId +
- '/pools/' + item.poolId +
- '/members/' + item.id;
+ if (item.listenerId) {
+ return 'project/load_balancer/' + item.loadbalancerId +
+ '/listeners/' + item.listenerId +
+ '/pools/' + item.poolId +
+ '/members/' + item.id;
+ } else {
+ return 'project/load_balancer/' + item.loadbalancerId +
+ '/pools/' + item.poolId +
+ '/members/' + item.id;
+ }
}
function getMembersPromise(params) {
@@ -131,10 +137,16 @@
}
function getHealthMonitorDetailsPath(item) {
- return 'project/load_balancer/' + item.loadbalancerId +
- '/listeners/' + item.listenerId +
- '/pools/' + item.poolId +
- '/healthmonitors/' + item.id;
+ if (item.listenerId) {
+ return 'project/load_balancer/' + item.loadbalancerId +
+ '/listeners/' + item.listenerId +
+ '/pools/' + item.poolId +
+ '/healthmonitors/' + item.id;
+ } else {
+ return 'project/load_balancer/' + item.loadbalancerId +
+ '/pools/' + item.poolId +
+ '/healthmonitors/' + item.id;
+ }
}
function getHealthMonitorsPromise(params) {
@@ -177,9 +189,15 @@
}
function getPoolDetailsPath(item) {
- return 'project/load_balancer/' +
- item.loadbalancerId + '/listeners/' +
- item.listeners[0].id + '/pools/' + item.id;
+ if (item.listeners.length > 0) {
+ return 'project/load_balancer/' +
+ item.loadbalancerId + '/listeners/' +
+ item.listeners[0].id + '/pools/' + item.id;
+ } else {
+ return 'project/load_balancer/' +
+ item.loadbalancerId +
+ '/pools/' + item.id;
+ }
}
function getListenersPromise(params) {
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.service.spec.js
index 1892d4e9..e5222821 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.service.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.service.spec.js
@@ -95,6 +95,9 @@
var myItem = {loadbalancerId: '123', id: '789', listeners: [{id: '456'}]};
expect(service.getPoolDetailsPath(myItem))
.toBe('project/load_balancer/123/listeners/456/pools/789');
+ myItem = {loadbalancerId: '123', id: '789', listeners: []};
+ expect(service.getPoolDetailsPath(myItem))
+ .toBe('project/load_balancer/123/pools/789');
});
it("getPoolsPromise provides a promise", inject(function($timeout) {
@@ -127,6 +130,13 @@
};
expect(service.getMemberDetailsPath(myItem))
.toBe('project/load_balancer/1/listeners/2/pools/3/members/4');
+ myItem = {
+ loadbalancerId: '1',
+ poolId: '3',
+ id: '4'
+ };
+ expect(service.getMemberDetailsPath(myItem))
+ .toBe('project/load_balancer/1/pools/3/members/4');
});
it("getMembersPromise provides a promise", inject(function($timeout) {
@@ -165,6 +175,13 @@
};
expect(service.getHealthMonitorDetailsPath(myItem))
.toBe('project/load_balancer/1/listeners/2/pools/3/healthmonitors/4');
+ myItem = {
+ loadbalancerId: '1',
+ poolId: '3',
+ id: '4'
+ };
+ expect(service.getHealthMonitorDetailsPath(myItem))
+ .toBe('project/load_balancer/1/pools/3/healthmonitors/4');
});
it("getHealthMonitorsPromise provides a promise", inject(function($timeout) {
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/delete/delete.action.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/delete/delete.action.service.js
index de0e4d34..3761b32c 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/delete/delete.action.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/delete/delete.action.service.js
@@ -119,9 +119,15 @@
});
if (actionResult.result.failed.length === 0 && actionResult.result.deleted.length > 0) {
- var path = 'project/load_balancer/' + loadbalancerId +
- '/listeners/' + listenerId +
- '/pools/' + poolId;
+ var path;
+ if (listenerId) {
+ path = 'project/load_balancer/' + loadbalancerId +
+ '/listeners/' + listenerId +
+ '/pools/' + poolId;
+ } else {
+ path = 'project/load_balancer/' + loadbalancerId +
+ '/pools/' + poolId;
+ }
$location.path(path);
}
return actionResult.result;
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/delete/delete.action.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/delete/delete.action.service.spec.js
index 2d59fc52..27c44421 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/delete/delete.action.service.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/delete/delete.action.service.spec.js
@@ -63,7 +63,7 @@
});
});
- it('should handle the action result properly', function() {
+ it('should handle the action result properly with listener', function() {
spyOn($location, 'path');
spyOn(deleteModalService, 'open').and.returnValue({then: angular.noop});
spyOn(lbaasv2API, 'deleteMember').and.callFake(angular.noop);
@@ -90,6 +90,33 @@
expect(result.failed[0].id).toBe(1);
});
+ it('should handle the action result properly without listener', function() {
+ spyOn($location, 'path');
+ spyOn(deleteModalService, 'open').and.returnValue({then: angular.noop});
+ spyOn(lbaasv2API, 'deleteMember').and.callFake(angular.noop);
+ service.perform({loadbalancerId: 1, poolId: 3, id: 1, name: 'one'});
+ var result = service.deleteResult({
+ fail: [],
+ pass: [{
+ context: {
+ id: 1
+ }
+ }]
+ });
+ var path = 'project/load_balancer/1/pools/3';
+ expect($location.path).toHaveBeenCalledWith(path);
+ expect(result.deleted[0].id).toBe(1);
+ result = service.deleteResult({
+ pass: [],
+ fail: [{
+ context: {
+ id: 1
+ }
+ }]
+ });
+ expect(result.failed[0].id).toBe(1);
+ });
+
describe('allow method', function() {
it('should use default policy if batch action', function () {
spyOn(policyAPI, 'ifAllowed');
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.js
index 23f28b60..cad2730a 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.js
@@ -63,6 +63,13 @@
ctrl.provisioningStatus = loadBalancersService.provisioningStatus;
ctrl.loadbalancer = loadbalancer;
ctrl.listener = listener;
+ if (!angular.equals({}, ctrl.listener)) {
+ ctrl.withListenerStyle = {};
+ ctrl.withoutListenerStyle = {display: 'none'};
+ } else {
+ ctrl.withListenerStyle = {display: 'none'};
+ ctrl.withoutListenerStyle = {};
+ }
ctrl.pool = pool;
ctrl.member = member;
ctrl.resourceType = typeRegistry.getResourceType(resourceType);
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.spec.js
index 0853d83f..dee5d627 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.spec.js
@@ -47,6 +47,19 @@
};
$timeout = _$timeout_;
scope = $rootScope.$new();
+ ctrl = $controller('MemberDetailController', {
+ $scope: scope,
+ loadbalancer: { id: '123' },
+ listener: {},
+ pool: { id: '123' },
+ member: { id: '123' },
+ 'horizon.framework.conf.resource-type-registry.service': service,
+ 'horizon.framework.util.actions.action-result.service': actionResultService,
+ 'horizon.framework.widgets.modal-wait-spinner.service': {
+ showModalSpinner: angular.noop,
+ hideModalSpinner: angular.noop
+ }
+ });
ctrl = $controller('MemberDetailController', {
$scope: scope,
loadbalancer: { id: '123' },
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.html
index c7f546b6..2acda866 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.html
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.html
@@ -4,8 +4,9 @@
Network
Load Balancers
{$ ::(ctrl.loadbalancer.name || ctrl.loadbalancer.id) $}
-
{$ ::(ctrl.listener.name || ctrl.listener.id) $}
-
{$ ::(ctrl.pool.name || ctrl.pool.id) $}
+
{$ :: (ctrl.listener.name || ctrl.listener.id) $}
+
{$ ::(ctrl.pool.name || ctrl.pool.id) $}
+
{$ ::(ctrl.pool.name || ctrl.pool.id) $}
{$ ::(ctrl.member.name || ctrl.member.id) $}
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/create/create.action.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/create/create.action.service.js
index ba1b5eb9..9b2bb848 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/create/create.action.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/create/create.action.service.js
@@ -27,9 +27,7 @@
'$q',
'horizon.dashboard.project.lbaasv2.workflow.modal',
'horizon.app.core.openstack-service-api.policy',
- 'horizon.framework.util.i18n.gettext',
- 'horizon.framework.util.q.extensions',
- '$routeParams'
+ 'horizon.framework.util.i18n.gettext'
];
/**
@@ -45,15 +43,13 @@
* @param workflowModal The LBaaS workflow modal service.
* @param policy The horizon policy service.
* @param gettext The horizon gettext function for translation.
- * @param qExtensions horizon extensions to the $q service.
- * @param $routeParams The angular $routeParams service.
*
* @returns The pool create service.
*/
function createService(
resourceType, actionResultService,
- $q, workflowModal, policy, gettext, qExtensions, $routeParams
+ $q, workflowModal, policy, gettext
) {
return workflowModal.init({
controller: 'CreatePoolWizardController',
@@ -66,7 +62,6 @@
function allowed() {
return $q.all([
- qExtensions.booleanAsPromise(!!$routeParams.listenerId),
policy.ifAllowed({ rules: [['neutron', 'create_pool']] })
]);
}
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/create/wizard.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/create/wizard.controller.js
index 9d0006cf..239fb0d4 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/create/wizard.controller.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/create/wizard.controller.js
@@ -40,6 +40,9 @@
'fa fa-cloud-download',
['pool', 'members', 'monitor']
);
+ if (!listenerId) {
+ listenerId = null;
+ }
scope.model.initialize('pool', false, loadbalancerId, listenerId);
}
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/create/wizard.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/create/wizard.controller.spec.js
index 88c89358..11751ff2 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/create/wizard.controller.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/create/wizard.controller.spec.js
@@ -40,6 +40,16 @@
beforeEach(inject(function ($controller) {
spyOn(model, 'initialize');
ctrl = $controller('CreatePoolWizardController', { $scope: scope });
+ ctrl = $controller(
+ 'CreatePoolWizardController',
+ {
+ $scope: scope,
+ $routeParams: {
+ loadBalancerId: '1',
+ listenerId: '2'
+ }
+ }
+ );
}));
it('defines the controller', function() {
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/delete/delete.action.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/delete/delete.action.service.js
index 34acc9d4..0f10683b 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/delete/delete.action.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/delete/delete.action.service.js
@@ -121,8 +121,13 @@
});
if (actionResult.result.failed.length === 0 && actionResult.result.deleted.length > 0) {
- var path = 'project/load_balancer/' + loadbalancerId +
- '/listeners/' + listenerId;
+ var path;
+ if (listenerId) {
+ path = 'project/load_balancer/' + loadbalancerId +
+ '/listeners/' + listenerId;
+ } else {
+ path = 'project/load_balancer/' + loadbalancerId;
+ }
$location.path(path);
}
return actionResult.result;
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/delete/delete.action.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/delete/delete.action.service.spec.js
index 174a3a15..4d55a372 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/delete/delete.action.service.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/delete/delete.action.service.spec.js
@@ -64,7 +64,7 @@
});
});
- it('should handle the action result properly', function() {
+ it('should handle the action result properly with listener', function() {
spyOn($location, 'path');
spyOn(deleteModalService, 'open').and.returnValue({then: angular.noop});
spyOn(lbaasv2API, 'deletePool').and.callFake(angular.noop);
@@ -91,6 +91,33 @@
expect(result.failed[0].id).toBe(1);
});
+ it('should handle the action result properly without listener', function() {
+ spyOn($location, 'path');
+ spyOn(deleteModalService, 'open').and.returnValue({then: angular.noop});
+ spyOn(lbaasv2API, 'deletePool').and.callFake(angular.noop);
+ service.perform({loadbalancerId: 1, id: 1, name: 'one'});
+ var result = service.deleteResult({
+ fail: [],
+ pass: [{
+ context: {
+ id: 1
+ }
+ }]
+ });
+ var path = 'project/load_balancer/1';
+ expect($location.path).toHaveBeenCalledWith(path);
+ expect(result.deleted[0].id).toBe(1);
+ result = service.deleteResult({
+ pass: [],
+ fail: [{
+ context: {
+ id: 1
+ }
+ }]
+ });
+ expect(result.failed[0].id).toBe(1);
+ });
+
describe('allow method', function() {
it('should use default policy if batch action', function () {
spyOn(policyAPI, 'ifAllowed');
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.js
index b0845b85..b11bdb8d 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.js
@@ -62,6 +62,11 @@
ctrl.loadBalancerAlgorithm = loadBalancersService.loadBalancerAlgorithm;
ctrl.loadbalancer = loadbalancer;
ctrl.listener = listener;
+ if (!angular.equals({}, ctrl.listener)) {
+ ctrl.withListenerStyle = {};
+ } else {
+ ctrl.withListenerStyle = {display: 'none'};
+ }
ctrl.pool = pool;
ctrl.listFunctionExtraParams = {
loadbalancerId: ctrl.loadbalancer.id,
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.spec.js
index 2bda4630..e2e4210f 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.spec.js
@@ -47,6 +47,18 @@
};
$timeout = _$timeout_;
scope = $rootScope.$new();
+ ctrl = $controller('PoolDetailController', {
+ $scope: scope,
+ loadbalancer: { id: '123' },
+ listener: {},
+ pool: { id: '123' },
+ 'horizon.framework.conf.resource-type-registry.service': service,
+ 'horizon.framework.util.actions.action-result.service': actionResultService,
+ 'horizon.framework.widgets.modal-wait-spinner.service': {
+ showModalSpinner: angular.noop,
+ hideModalSpinner: angular.noop
+ }
+ });
ctrl = $controller('PoolDetailController', {
$scope: scope,
loadbalancer: { id: '123' },
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.html
index 51778f85..cb18e180 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.html
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.html
@@ -4,7 +4,7 @@
Network
Load Balancers
{$ ::(ctrl.loadbalancer.name || ctrl.loadbalancer.id) $}
-
{$ ::(ctrl.listener.name || ctrl.listener.id) $}
+
{$ :: (ctrl.listener.name || ctrl.listener.id) $}
{$ ::(ctrl.pool.name || ctrl.pool.id) $}
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.js
index b902da01..eff26953 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.js
@@ -86,6 +86,7 @@
subnets: [],
members: [],
listenerProtocols: ['HTTP', 'TCP', 'TERMINATED_HTTPS', 'HTTPS'],
+ poolProtocols: ['HTTP', 'HTTPS', 'PROXY', 'TCP'],
methods: ['LEAST_CONNECTIONS', 'ROUND_ROBIN', 'SOURCE_IP'],
types: ['SOURCE_IP', 'HTTP_COOKIE', 'APP_COOKIE'],
monitorTypes: ['HTTP', 'PING', 'TCP'],
@@ -243,12 +244,20 @@
model.context.submit = createPool;
// We get the listener details here because we need to know the listener protocol
// in order to default the new pool's protocol to match.
- return $q.all([
- lbaasv2API.getListener(model.spec.parentResourceId).then(onGetListener),
- neutronAPI.getSubnets().then(onGetSubnets),
- neutronAPI.getPorts().then(onGetPorts),
- novaAPI.getServers().then(onGetServers)
- ]).then(initMemberAddresses);
+ if (model.spec.parentResourceId) {
+ return $q.all([
+ lbaasv2API.getListener(model.spec.parentResourceId).then(onGetListener),
+ neutronAPI.getSubnets().then(onGetSubnets),
+ neutronAPI.getPorts().then(onGetPorts),
+ novaAPI.getServers().then(onGetServers)
+ ]).then(initMemberAddresses);
+ } else {
+ return $q.all([
+ neutronAPI.getSubnets().then(onGetSubnets),
+ neutronAPI.getPorts().then(onGetPorts),
+ novaAPI.getServers().then(onGetServers)
+ ]).then(initMemberAddresses);
+ }
}
function initCreateMonitor() {
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.spec.js
index 5ab25445..b01ae577 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.spec.js
@@ -451,7 +451,7 @@
});
});
- describe('Post initialize model (create pool)', function() {
+ describe('Post initialize model (create pool with listener)', function() {
beforeEach(function() {
includeChildResources = false;
@@ -489,6 +489,44 @@
});
});
+ describe('Post initialize model (create pool without listener)', function() {
+
+ beforeEach(function() {
+ includeChildResources = false;
+ model.initialize('pool', false, '1234');
+ scope.$apply();
+ });
+
+ it('should initialize model properties', function() {
+ expect(model.initializing).toBe(false);
+ expect(model.initialized).toBe(true);
+ expect(model.subnets.length).toBe(2);
+ expect(model.members.length).toBe(2);
+ expect(model.certificates.length).toBe(0);
+ expect(model.listenerPorts.length).toBe(0);
+ expect(model.spec).toBeDefined();
+ expect(model.spec.loadbalancer_id).toBe('1234');
+ expect(model.spec.parentResourceId).toBeUndefined();
+ expect(model.spec.loadbalancer).toBeDefined();
+ expect(model.spec.listener).toBeDefined();
+ expect(model.spec.pool).toBeDefined();
+ expect(model.spec.members.length).toBe(0);
+ expect(model.spec.certificates).toEqual([]);
+ expect(model.spec.monitor).toBeDefined();
+ expect(model.certificatesError).toBe(false);
+ });
+
+ it('should initialize names', function() {
+ expect(model.spec.pool.name).toBe('Pool 1');
+ });
+
+ it('should initialize context properties', function() {
+ expect(model.context.resource).toBe('pool');
+ expect(model.context.id).toBeFalsy();
+ expect(model.context.submit).toBeDefined();
+ });
+ });
+
describe('Post initialize model (create health monitor)', function() {
beforeEach(function() {
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/pool/pool.help.html b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/pool/pool.help.html
index e2b9172d..4ac2f545 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/pool/pool.help.html
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/pool/pool.help.html
@@ -19,6 +19,12 @@
+
+ Protocol:
+
+ The protocol for which this pool and its members listen. A valid value is HTTP, HTTPS, PROXY, or TCP.
+
+
Session Persistence:
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/pool/pool.html b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/pool/pool.html
index d2e7d4ac..35aaaba8 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/pool/pool.html
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/pool/pool.html
@@ -21,6 +21,40 @@
+
+
+
+
+
+ Algorithm
+
+
+
+
+
+
+
+
+
+
+ Protocol
+
+
+
+
+ {$ protocol $}
+
+
+
+
+
+
+
@@ -46,24 +80,6 @@
-
-
-
-
-
- Algorithm
-
-
-
-
-
-
-
-
-
diff --git a/releasenotes/notes/list-pools-on-lb-details-page-eb0400bdb2b3650f.yaml b/releasenotes/notes/list-pools-on-lb-details-page-eb0400bdb2b3650f.yaml
new file mode 100644
index 00000000..22e380f7
--- /dev/null
+++ b/releasenotes/notes/list-pools-on-lb-details-page-eb0400bdb2b3650f.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Pools attached to a load balancer are now listed on the load balancer
+ details page.