diff --git a/octavia_dashboard/api/rest/lbaasv2.py b/octavia_dashboard/api/rest/lbaasv2.py
index 0324b7d0..df65362b 100644
--- a/octavia_dashboard/api/rest/lbaasv2.py
+++ b/octavia_dashboard/api/rest/lbaasv2.py
@@ -661,6 +661,24 @@ class Pools(generic.View):
"""
url_regex = r'lbaas/pools/$'
+ @rest_utils.ajax()
+ def get(self, request):
+ """List of pools for the current project.
+
+ The listing result is an object with property "items".
+ """
+ loadbalancer_id = request.GET.get('loadbalancerId')
+ listener_id = request.GET.get('listenerId')
+ conn = _get_sdk_connection(request)
+ pool_list = _sdk_object_to_list(conn.load_balancer.pools(
+ project_id=request.user.project_id))
+
+ if loadbalancer_id or listener_id:
+ pool_list = self._filter_pools(pool_list,
+ loadbalancer_id,
+ listener_id)
+ return {'items': pool_list}
+
@rest_utils.ajax()
def post(self, request):
"""Create a new pool.
@@ -672,6 +690,24 @@ class Pools(generic.View):
'listener_id': request.DATA.get('parentResourceId')}
return create_pool(request, **kwargs)
+ def _filter_pools(self, pool_list, loadbalancer_id, listener_id):
+ filtered_pools = []
+
+ for pool in pool_list:
+ if loadbalancer_id:
+ if pool['loadbalancers'][0]['id'] == loadbalancer_id:
+ if listener_id:
+ if (pool['listeners'] and
+ pool['listeners'][0]['id'] == listener_id):
+ filtered_pools.append(pool)
+ else:
+ filtered_pools.append(pool)
+ elif (pool['listeners'] and
+ pool['listeners'][0]['id'] == listener_id):
+ filtered_pools.append(pool)
+
+ return filtered_pools
+
@urls.register
class Pool(generic.View):
@@ -819,6 +855,26 @@ class HealthMonitors(generic.View):
"""
url_regex = r'lbaas/healthmonitors/$'
+ @rest_utils.ajax()
+ def get(self, request):
+ """List of health monitors for the current project.
+
+ The listing result is an object with property "items".
+ """
+ pool_id = request.GET.get('poolId')
+ conn = _get_sdk_connection(request)
+ health_monitor_list = _sdk_object_to_list(
+ conn.load_balancer.health_monitors(
+ project_id=request.user.project_id
+ )
+ )
+
+ if pool_id:
+ health_monitor_list = self._filter_health_monitors(
+ health_monitor_list,
+ pool_id)
+ return {'items': health_monitor_list}
+
@rest_utils.ajax()
def post(self, request):
"""Create a new health monitor.
@@ -828,6 +884,15 @@ class HealthMonitors(generic.View):
'pool_id': request.DATA.get('parentResourceId')}
return create_health_monitor(request, **kwargs)
+ def _filter_health_monitors(self, health_monitor_list, pool_id):
+ filtered_health_monitors = []
+
+ for health_monitor in health_monitor_list:
+ if health_monitor['pools'][0]['id'] == pool_id:
+ filtered_health_monitors.append(health_monitor)
+
+ return filtered_health_monitors
+
@urls.register
class HealthMonitor(generic.View):
diff --git a/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js b/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js
index 0fef13c1..6ebd55c4 100644
--- a/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js
+++ b/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js
@@ -46,6 +46,7 @@
createListener: createListener,
editListener: editListener,
deleteListener: deleteListener,
+ getPools: getPools,
getPool: getPool,
createPool: createPool,
editPool: editPool,
@@ -54,6 +55,7 @@
getMember: getMember,
deleteMember: deleteMember,
editMember: editMember,
+ getHealthMonitors: getHealthMonitors,
getHealthMonitor: getHealthMonitor,
deleteHealthMonitor: deleteHealthMonitor,
createHealthMonitor: createHealthMonitor,
@@ -242,6 +244,38 @@
// Pools
+ /**
+ * @name horizon.app.core.openstack-service-api.lbaasv2.getPools
+ * @description
+ * Get the list of pools.
+ * If a loadbalancer ID is passed as a parameter, the returning list of
+ * pools will be filtered to include only those pools under the
+ * specified loadbalancer.
+ * @param {string} loadbalancerId
+ * Specifies the id of the loadbalancer to request pools for.
+ * @param {string} listenerId
+ * Specifies the id of the listener to request pools for.
+ *
+ * The listing result is an object with property "items". Each item is
+ * a pool.
+ */
+
+ function getPools(loadbalancerId, listenerId) {
+ var params = $.extend({},
+ {
+ loadbalancerId: loadbalancerId,
+ listenerId: listenerId
+ }
+ );
+ if (!$.isEmptyObject(params)) {
+ params = { params: params };
+ }
+ return apiService.get('/api/lbaas/pools/', params)
+ .error(function () {
+ toastService.add('error', gettext('Unable to retrieve pools.'));
+ });
+ }
+
/**
* @name horizon.app.core.openstack-service-api.lbaasv2.getPool
* @description
@@ -408,6 +442,28 @@
* Specifies the id of the health monitor.
*/
+ /**
+ * @name horizon.app.core.openstack-service-api.lbaasv2.getHealthMonitors
+ * @description
+ * Get the list of healthmonitors.
+ * If a pool ID is passed as a parameter, the returning list of
+ * healthmonitors will be filtered to include only those healthmonitors under the
+ * specified pool.
+ * @param {string} id
+ * Specifies the id of the pool to request healthmonitors for.
+ *
+ * The listing result is an object with property "items". Each item is
+ * a healthmonitor.
+ */
+
+ function getHealthMonitors(id) {
+ var params = id ? {params: {poolId: id}} : {};
+ return apiService.get('/api/lbaas/healthmonitors/', params)
+ .error(function () {
+ toastService.add('error', gettext('Unable to retrieve health monitors.'));
+ });
+ }
+
function getHealthMonitor(monitorId) {
return apiService.get('/api/lbaas/healthmonitors/' + monitorId + '/')
.error(function () {
diff --git a/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js b/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js
index fee48608..118b83fd 100644
--- a/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js
+++ b/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js
@@ -90,6 +90,37 @@
error: 'Unable to retrieve listener.',
testInput: [ '1234', false ]
},
+ {
+ func: 'getPools',
+ method: 'get',
+ path: '/api/lbaas/pools/',
+ error: 'Unable to retrieve pools.',
+ testInput: [ '1234' ],
+ data: { params: { loadbalancerId: '1234' } }
+ },
+ {
+ func: 'getPools',
+ method: 'get',
+ path: '/api/lbaas/pools/',
+ error: 'Unable to retrieve pools.',
+ testInput: [ '1234', '5678' ],
+ data: { params: { loadbalancerId: '1234', listenerId: '5678' } }
+ },
+ {
+ func: 'getPools',
+ method: 'get',
+ path: '/api/lbaas/pools/',
+ error: 'Unable to retrieve pools.',
+ testInput: [ undefined, '5678' ],
+ data: { params: { listenerId: '5678' } }
+ },
+ {
+ func: 'getPools',
+ method: 'get',
+ path: '/api/lbaas/pools/',
+ data: {},
+ error: 'Unable to retrieve pools.'
+ },
{
func: 'getPool',
method: 'get',
@@ -142,6 +173,21 @@
data: { weight: 2 },
testInput: [ '1234', '5678', { weight: 2 } ]
},
+ {
+ func: 'getHealthMonitors',
+ method: 'get',
+ path: '/api/lbaas/healthmonitors/',
+ error: 'Unable to retrieve health monitors.',
+ testInput: [ '1234' ],
+ data: { params: { poolId: '1234' } }
+ },
+ {
+ func: 'getHealthMonitors',
+ method: 'get',
+ path: '/api/lbaas/healthmonitors/',
+ data: {},
+ error: 'Unable to retrieve health monitors.'
+ },
{
func: 'getHealthMonitor',
method: 'get',
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.js
index 91274031..57f29e57 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -21,68 +22,46 @@
.factory('horizon.dashboard.project.lbaasv2.healthmonitors.actions.create', createService);
createService.$inject = [
- '$q',
- '$location',
+ 'horizon.dashboard.project.lbaasv2.healthmonitors.resourceType',
+ 'horizon.framework.util.actions.action-result.service',
'horizon.dashboard.project.lbaasv2.workflow.modal',
'horizon.app.core.openstack-service-api.policy',
- 'horizon.framework.util.i18n.gettext',
- 'horizon.framework.util.q.extensions'
+ 'horizon.framework.util.i18n.gettext'
];
/**
* @ngDoc factory
* @name horizon.dashboard.project.lbaasv2.healthmonitors.actions.createService
+ *
* @description
* Provides the service for creating a health monitor resource.
- * @param $q The angular service for promises.
- * @param $location The angular $location service.
+ *
+ * @param resourceType The health monitor resource type.
+ * @param actionResultService The horizon action result service.
* @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.
+ *
* @returns The health monitor create service.
*/
- function createService($q, $location, workflowModal, policy, gettext, qExtensions) {
- var loadbalancerId, listenerId, poolId, statePromise;
-
- var create = workflowModal.init({
+ function createService(resourceType, actionResultService, workflowModal, policy, gettext) {
+ return workflowModal.init({
controller: 'CreateHealthMonitorWizardController',
message: gettext('A new health monitor is being created.'),
- handle: onCreate,
+ handle: handle,
allowed: allowed
});
- var service = {
- init: init,
- create: create
- };
-
- return service;
-
- //////////////
-
- function init(_loadbalancerId_, _listenerId_, _statePromise_) {
- loadbalancerId = _loadbalancerId_;
- listenerId = _listenerId_;
- statePromise = _statePromise_;
- return service;
+ function allowed() {
+ return policy.ifAllowed({ rules: [['neutron', 'create_health_monitor']] });
}
- function allowed(pool) {
- poolId = pool.id;
- return $q.all([
- statePromise,
- qExtensions.booleanAsPromise(!pool.health_monitor_id),
- policy.ifAllowed({ rules: [['neutron', 'create_health_monitor']] })
- ]);
+ function handle(response) {
+ var newHealthMonitor = response.data;
+ return actionResultService.getActionResult()
+ .created(resourceType, newHealthMonitor.id)
+ .result;
}
-
- function onCreate(response) {
- var healthMonitorId = response.data.id;
- $location.path('project/load_balancer/' + loadbalancerId + '/listeners/' +
- listenerId + '/pools/' + poolId + '/healthmonitors/' + healthMonitorId);
- }
-
}
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.spec.js
index 6ea7e956..4d37cf40 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.spec.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -17,89 +18,25 @@
'use strict';
describe('LBaaS v2 Create Health Monitor Action Service', function() {
- var scope, $q, $location, policy, init, service, loadBalancerState;
+ var policy, service;
- function allowed(item) {
- spyOn(policy, 'ifAllowed').and.returnValue(true);
- var promise = service.create.allowed(item);
- var allowed;
- promise.then(function() {
- allowed = true;
- }, function() {
- allowed = false;
- });
- scope.$apply();
- expect(policy.ifAllowed).toHaveBeenCalledWith(
- {rules: [['neutron', 'create_health_monitor']]});
- return allowed;
- }
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
beforeEach(module('horizon.dashboard.project.lbaasv2'));
- beforeEach(module(function($provide) {
- $provide.value('$uibModal', {
- open: function() {
- return {
- result: {
- then: function(func) {
- func({ data: { id: 'healthmonitor1' } });
- }
- }
- };
- }
- });
- }));
-
beforeEach(inject(function ($injector) {
- scope = $injector.get('$rootScope').$new();
- $q = $injector.get('$q');
policy = $injector.get('horizon.app.core.openstack-service-api.policy');
- $location = $injector.get('$location');
service = $injector.get('horizon.dashboard.project.lbaasv2.healthmonitors.actions.create');
- init = service.init;
- loadBalancerState = $q.defer();
}));
- it('should define the correct service properties', function() {
- expect(service.init).toBeDefined();
- expect(service.create).toBeDefined();
+ it('should check policy to allow creating a health monitor', function() {
+ spyOn(policy, 'ifAllowed').and.returnValue(true);
+ expect(service.allowed()).toBe(true);
+ expect(policy.ifAllowed)
+ .toHaveBeenCalledWith({rules: [['neutron', 'create_health_monitor']]});
});
- it('should have the "allowed" and "perform" functions', function() {
- expect(service.create.allowed).toBeDefined();
- expect(service.create.perform).toBeDefined();
- });
-
- it('should allow creating a health monitor under an ACTIVE load balancer', function() {
- loadBalancerState.resolve();
- init('active', '1', loadBalancerState.promise);
- expect(allowed({})).toBe(true);
- });
-
- it('should not allow creating a health monitor under a NON-ACTIVE load balancer', function() {
- loadBalancerState.reject();
- init('non-active', '1', loadBalancerState.promise);
- expect(allowed({})).toBe(false);
- });
-
- it('should not allow creating a health monitor if one already exists', function() {
- loadBalancerState.resolve();
- init('active', '1', loadBalancerState.promise);
- expect(allowed({ health_monitor_id: '1234' })).toBe(false);
- });
-
- it('should redirect after create', function() {
- loadBalancerState.resolve();
- spyOn($location, 'path').and.callThrough();
- init('loadbalancer1', 'listener1', loadBalancerState.promise).create.allowed({id: 'pool1'});
- service.create.perform();
- expect($location.path).toHaveBeenCalledWith(
- 'project/load_balancer/loadbalancer1/listeners/listener1/pools/pool1/' +
- 'healthmonitors/healthmonitor1');
+ it('should handle the action result properly', function() {
+ var result = service.handle({data: {id: 1}});
+ expect(result.created[0].id).toBe(1);
});
});
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/wizard.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/wizard.controller.js
index 8356fe1e..644aa4c7 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/wizard.controller.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/wizard.controller.js
@@ -32,6 +32,7 @@
$scope, $routeParams, model, workflowService, gettext
) {
var loadbalancerId = $routeParams.loadbalancerId;
+ var poolId = $routeParams.poolId;
var scope = $scope;
scope.model = model;
scope.submit = scope.model.submit;
@@ -40,7 +41,7 @@
'fa fa-cloud-download',
['monitor']
);
- scope.model.initialize('monitor', false, loadbalancerId, scope.launchContext.id);
+ scope.model.initialize('monitor', false, loadbalancerId, poolId);
}
})();
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 6e56543b..2fcdfb75 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
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -21,9 +22,9 @@
.factory('horizon.dashboard.project.lbaasv2.healthmonitors.actions.delete', deleteService);
deleteService.$inject = [
- '$q',
+ 'horizon.dashboard.project.lbaasv2.healthmonitors.resourceType',
+ 'horizon.framework.util.actions.action-result.service',
'$location',
- '$route',
'horizon.framework.widgets.modal.deleteModalService',
'horizon.app.core.openstack-service-api.lbaasv2',
'horizon.app.core.openstack-service-api.policy',
@@ -33,24 +34,27 @@
/**
* @ngDoc factory
* @name horizon.dashboard.project.lbaasv2.healthmonitors.actions.deleteService
+ *
* @description
* Brings up the delete health monitor confirmation modal dialog.
* On submit, deletes selected health monitor.
* On cancel, does nothing.
- * @param $q The angular service for promises.
+ *
+ * @param resourceType The health monitor resource type.
+ * @param actionResultService The horizon action result service.
* @param $location The angular $location service.
- * @param $route The angular $route service.
* @param deleteModal The horizon delete modal service.
* @param api The LBaaS v2 API service.
* @param policy The horizon policy service.
* @param gettext The horizon gettext function for translation.
+ *
* @returns The health monitor delete service.
*/
function deleteService(
- $q, $location, $route, deleteModal, api, policy, gettext
+ resourceType, actionResultService, $location, deleteModal, api, policy, gettext
) {
- var loadbalancerId, listenerId, poolId, statePromise;
+ var loadbalancerId, listenerId, poolId;
var context = {
labels: {
title: gettext('Confirm Delete Health Monitor'),
@@ -68,50 +72,51 @@
var service = {
perform: perform,
allowed: allowed,
- init: init
+ deleteResult: deleteResult // exposed just for testing
};
return service;
//////////////
- function init(_loadbalancerId_, _listenerId_, _poolId_, _statePromise_) {
- loadbalancerId = _loadbalancerId_;
- listenerId = _listenerId_;
- poolId = _poolId_;
- statePromise = _statePromise_;
- return service;
- }
-
- function perform(item) {
- deleteModal.open({ $emit: actionComplete }, [item], context);
- }
-
function allowed(/*item*/) {
- return $q.all([
- statePromise,
- // This rule is made up and should therefore always pass. I assume at some point there
- // will be a valid rule similar to this that we will want to use.
- policy.ifAllowed({ rules: [['neutron', 'delete_health_monitor']] })
- ]);
+ // This rule is made up and should therefore always pass. I assume at some point there
+ // will be a valid rule similar to this that we will want to use.
+ return policy.ifAllowed({ rules: [['neutron', 'delete_health_monitor']] });
}
- function deleteItem(id) {
- return api.deleteHealthMonitor(id, true);
+ function perform(items, scope) {
+ var healthMonitors = angular.isArray(items) ? items : [items];
+ healthMonitors.map(function(item) {
+ loadbalancerId = item.loadbalancerId;
+ listenerId = item.listenerId;
+ poolId = item.poolId;
+ });
+ return deleteModal.open(scope, healthMonitors, context).then(deleteResult);
}
- function actionComplete(eventType) {
- if (eventType === context.failedEvent) {
- // Error, reload page
- $route.reload();
- } else {
- // Success, go back to pool details page
+ function deleteResult(deleteModalResult) {
+ // To make the result of this action generically useful, reformat the return
+ // from the deleteModal into a standard form
+ var actionResult = actionResultService.getActionResult();
+ deleteModalResult.pass.forEach(function markDeleted(item) {
+ actionResult.deleted(resourceType, item.context.id);
+ });
+ deleteModalResult.fail.forEach(function markFailed(item) {
+ actionResult.failed(resourceType, item.context.id);
+ });
+
+ if (actionResult.result.failed.length === 0 && actionResult.result.deleted.length > 0) {
var path = 'project/load_balancer/' + loadbalancerId +
'/listeners/' + listenerId +
'/pools/' + poolId;
$location.path(path);
}
+ return actionResult.result;
}
+ function deleteItem(id) {
+ return api.deleteHealthMonitor(id, true);
+ }
}
})();
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 70a17f1c..1e2d3613 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
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -17,140 +18,87 @@
'use strict';
describe('LBaaS v2 Health Monitor Delete Service', function() {
- var service, policy, modal, lbaasv2Api, $scope, $location, $q, toast, monitor;
-
- function allowed(item) {
- spyOn(policy, 'ifAllowed').and.returnValue(makePromise());
- var promise = service.allowed(item);
- var allowed;
- promise.then(function() {
- allowed = true;
- }, function() {
- allowed = false;
- });
- $scope.$apply();
- expect(policy.ifAllowed)
- .toHaveBeenCalledWith({rules: [['neutron', 'delete_health_monitor']]});
- return allowed;
- }
-
- function makePromise(reject) {
- var def = $q.defer();
- def[reject ? 'reject' : 'resolve']();
- return def.promise;
- }
-
- function isActionable(id) {
- if (id === 'active') {
- return $q.when();
- } else {
- return $q.reject();
- }
- }
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
+ beforeEach(module('horizon.app.core'));
beforeEach(module('horizon.dashboard.project.lbaasv2'));
+ beforeEach(module('horizon.framework'));
- beforeEach(function() {
- monitor = { id: '1', name: 'HealthMonitor1' };
- });
+ var deleteModalService, service, lbaasv2API, policyAPI, $location;
- beforeEach(module(function($provide) {
- $provide.value('$uibModal', {
- open: function() {
- return {
- result: makePromise()
- };
- }
- });
- $provide.value('horizon.app.core.openstack-service-api.lbaasv2', {
- deleteHealthMonitor: function() {
- return makePromise();
- }
- });
- $provide.value('$location', {
- path: function() {
- return '';
- }
- });
- }));
-
- beforeEach(inject(function ($injector) {
- policy = $injector.get('horizon.app.core.openstack-service-api.policy');
- lbaasv2Api = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
- modal = $injector.get('horizon.framework.widgets.modal.deleteModalService');
- $scope = $injector.get('$rootScope').$new();
- $location = $injector.get('$location');
- $q = $injector.get('$q');
- toast = $injector.get('horizon.framework.widgets.toast.service');
+ beforeEach(inject(function($injector) {
service = $injector.get('horizon.dashboard.project.lbaasv2.healthmonitors.actions.delete');
- service.init('1', '2', '3', isActionable('active'));
- $scope.$apply();
+ lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
+ deleteModalService = $injector.get('horizon.framework.widgets.modal.deleteModalService');
+ policyAPI = $injector.get('horizon.app.core.openstack-service-api.policy');
+ $location = $injector.get('$location');
}));
- it('should have the "allowed" and "perform" functions', function() {
- expect(service.allowed).toBeDefined();
- expect(service.perform).toBeDefined();
+ describe('perform method', function() {
+ beforeEach(function () {
+ // just need for this to return something that looks like a promise but does nothing
+ spyOn(deleteModalService, 'open').and.returnValue({then: angular.noop});
+ });
+
+ it('should open the modal with correct label', function () {
+ service.perform({name: 'spam'});
+ var labels = deleteModalService.open.calls.argsFor(0)[2].labels;
+ expect(deleteModalService.open).toHaveBeenCalled();
+ angular.forEach(labels, function eachLabel(label) {
+ expect(label.toLowerCase()).toContain('health monitor');
+ });
+ });
+
+ it('should open the delete modal with correct entities', function () {
+ service.perform([{name: 'one'}, {name: 'two'}]);
+ var entities = deleteModalService.open.calls.argsFor(0)[1];
+ expect(deleteModalService.open).toHaveBeenCalled();
+ expect(entities.length).toEqual(2);
+ });
+
+ it('should pass in a function that deletes a health monitor', function () {
+ spyOn(lbaasv2API, 'deleteHealthMonitor').and.callFake(angular.noop);
+ service.perform({id: 1, name: 'one'});
+ var contextArg = deleteModalService.open.calls.argsFor(0)[2];
+ var deleteFunction = contextArg.deleteEntity;
+ deleteFunction(1);
+ expect(lbaasv2API.deleteHealthMonitor).toHaveBeenCalledWith(1, true);
+ });
});
- it('should allow deleting health monitor from load balancer in ACTIVE state', function() {
- expect(allowed()).toBe(true);
- });
-
- it('should not allow deleting health monitor from load balancer in PENDING state', function() {
- service.init('1', '2', '3', isActionable('pending'));
- expect(allowed()).toBe(false);
- });
-
- it('should open the delete modal', function() {
- spyOn(modal, 'open');
- service.perform(monitor);
- $scope.$apply();
- expect(modal.open.calls.count()).toBe(1);
- var args = modal.open.calls.argsFor(0);
- expect(args.length).toBe(3);
- expect(args[0]).toEqual({ $emit: jasmine.any(Function) });
- expect(args[1]).toEqual([monitor]);
- expect(args[2]).toEqual(jasmine.objectContaining({
- labels: jasmine.any(Object),
- deleteEntity: jasmine.any(Function)
- }));
- expect(args[2].labels.title).toBe('Confirm Delete Health Monitor');
- });
-
- it('should pass function to modal that deletes the health monitor', function() {
- spyOn(modal, 'open').and.callThrough();
- spyOn(lbaasv2Api, 'deleteHealthMonitor').and.callThrough();
- service.perform(monitor);
- $scope.$apply();
- expect(lbaasv2Api.deleteHealthMonitor.calls.count()).toBe(1);
- expect(lbaasv2Api.deleteHealthMonitor).toHaveBeenCalledWith('1', true);
- });
-
- it('should show message if any items fail to be deleted', function() {
- spyOn(modal, 'open').and.callThrough();
- spyOn(lbaasv2Api, 'deleteHealthMonitor').and.returnValue(makePromise(true));
- spyOn(toast, 'add');
- service.perform(monitor);
- $scope.$apply();
- expect(modal.open).toHaveBeenCalled();
- expect(lbaasv2Api.deleteHealthMonitor.calls.count()).toBe(1);
- expect(toast.add).toHaveBeenCalledWith('error', 'The following health monitor could not ' +
- 'be deleted: HealthMonitor1.');
- });
-
- it('should return to pool details after delete', function() {
- var path = 'project/load_balancer/1/listeners/2/pools/3';
+ it('should handle the action result properly', function() {
spyOn($location, 'path');
- spyOn(toast, 'add');
- service.perform(monitor);
- $scope.$apply();
+ spyOn(deleteModalService, 'open').and.returnValue({then: angular.noop});
+ spyOn(lbaasv2API, 'deleteHealthMonitor').and.callFake(angular.noop);
+ service.perform({loadbalancerId: 1, listenerId: 2, poolId: 3, id: 1, name: 'one'});
+ var result = service.deleteResult({
+ fail: [],
+ pass: [{
+ context: {
+ id: 1
+ }
+ }]
+ });
+ var path = 'project/load_balancer/1/listeners/2/pools/3';
expect($location.path).toHaveBeenCalledWith(path);
- expect(toast.add).toHaveBeenCalledWith('success', 'Deleted health monitor: HealthMonitor1.');
+ 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');
+ service.allowed();
+ expect(policyAPI.ifAllowed).toHaveBeenCalled();
+ });
+ }); // end of allowed
+
+ }); // end of delete
+
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/edit/edit.action.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/edit/edit.action.service.js
index baf61537..7020a04f 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/edit/edit.action.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/edit/edit.action.service.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -21,8 +22,8 @@
.factory('horizon.dashboard.project.lbaasv2.healthmonitors.actions.edit', editService);
editService.$inject = [
- '$q',
- '$route',
+ 'horizon.dashboard.project.lbaasv2.healthmonitors.resourceType',
+ 'horizon.framework.util.actions.action-result.service',
'horizon.dashboard.project.lbaasv2.workflow.modal',
'horizon.app.core.openstack-service-api.policy',
'horizon.framework.util.i18n.gettext'
@@ -31,50 +32,36 @@
/**
* @ngDoc factory
* @name horizon.dashboard.project.lbaasv2.healthmonitors.actions.editService
+ *
* @description
* Provides the service for editing a health monitor resource.
- * @param $q The angular service for promises.
- * @param $route The angular $route service.
+ *
+ * @param resourceType The health monitor resource type.
+ * @param actionResultService The horizon action result service.
* @param workflowModal The LBaaS workflow modal service.
* @param policy The horizon policy service.
* @param gettext The horizon gettext function for translation.
+ *
* @returns The health monitor edit service.
*/
- function editService($q, $route, workflowModal, policy, gettext) {
- var statePromise;
+ function editService(resourceType, actionResultService, workflowModal, policy, gettext) {
- var edit = workflowModal.init({
+ return workflowModal.init({
controller: 'EditHealthMonitorWizardController',
message: gettext('The health monitor has been updated.'),
handle: handle,
allowed: allowed
});
- var service = {
- init: init,
- edit: edit
- };
-
- return service;
-
- //////////////
-
- function init(_statePromise_) {
- statePromise = _statePromise_;
- return service;
- }
-
function allowed(/*healthmonitor*/) {
- return $q.all([
- statePromise,
- policy.ifAllowed({ rules: [['neutron', 'update_health_monitor']] })
- ]);
+ return policy.ifAllowed({ rules: [['neutron', 'update_health_monitor']] });
}
- function handle(/*response*/) {
- $route.reload();
+ function handle(response) {
+ return actionResultService.getActionResult()
+ .updated(resourceType, response.config.data.monitor.id)
+ .result;
}
-
}
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/edit/edit.action.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/edit/edit.action.service.spec.js
index 98522853..08cea7ce 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/edit/edit.action.service.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/edit/edit.action.service.spec.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -17,81 +18,25 @@
'use strict';
describe('LBaaS v2 Edit Health Monitor Action Service', function() {
- var scope, $q, $route, policy, init, service, loadBalancerState;
+ var policy, service;
- function allowed(item) {
- spyOn(policy, 'ifAllowed').and.returnValue(true);
- var promise = service.edit.allowed(item);
- var allowed;
- promise.then(function() {
- allowed = true;
- }, function() {
- allowed = false;
- });
- scope.$apply();
- expect(policy.ifAllowed).toHaveBeenCalledWith(
- {rules: [['neutron', 'update_health_monitor']]});
- return allowed;
- }
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
beforeEach(module('horizon.dashboard.project.lbaasv2'));
- beforeEach(module(function($provide) {
- $provide.value('$uibModal', {
- open: function() {
- return {
- result: {
- then: function(func) {
- func({ data: { id: 'healthmonitor1' } });
- }
- }
- };
- }
- });
- }));
-
beforeEach(inject(function ($injector) {
- scope = $injector.get('$rootScope').$new();
- $q = $injector.get('$q');
policy = $injector.get('horizon.app.core.openstack-service-api.policy');
- $route = $injector.get('$route');
service = $injector.get('horizon.dashboard.project.lbaasv2.healthmonitors.actions.edit');
- init = service.init;
- loadBalancerState = $q.defer();
}));
- it('should define the correct service properties', function() {
- expect(service.init).toBeDefined();
- expect(service.edit).toBeDefined();
+ it('should check policy to allow editing a health monitor', function() {
+ spyOn(policy, 'ifAllowed').and.returnValue(true);
+ expect(service.allowed()).toBe(true);
+ expect(policy.ifAllowed)
+ .toHaveBeenCalledWith({rules: [['neutron', 'update_health_monitor']]});
});
- it('should have the "allowed" and "perform" functions', function() {
- expect(service.edit.allowed).toBeDefined();
- expect(service.edit.perform).toBeDefined();
- });
-
- it('should allow edit a health monitor under an ACTIVE load balancer', function() {
- loadBalancerState.resolve();
- init(loadBalancerState.promise);
- expect(allowed({})).toBe(true);
- });
-
- it('should not allow editing a health monitor under a NON-ACTIVE load balancer', function() {
- loadBalancerState.reject();
- init(loadBalancerState.promise);
- expect(allowed({})).toBe(false);
- });
-
- it('should reload page after edit', function() {
- loadBalancerState.resolve();
- spyOn($route, 'reload');
- init(loadBalancerState.promise).edit.allowed({});
- service.edit.perform();
- expect($route.reload).toHaveBeenCalled();
+ it('should handle the action result properly', function() {
+ var result = service.handle({config: {data: {monitor: {id: 1}}}});
+ expect(result.updated[0].id).toBe(1);
});
});
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/row-actions.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/row-actions.service.js
deleted file mode 100644
index 9bc4394a..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/row-actions.service.js
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.healthmonitors')
- .factory('horizon.dashboard.project.lbaasv2.healthmonitors.actions.rowActions',
- rowActions);
-
- rowActions.$inject = [
- 'horizon.framework.util.i18n.gettext',
- 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
- 'horizon.dashboard.project.lbaasv2.healthmonitors.actions.edit',
- 'horizon.dashboard.project.lbaasv2.healthmonitors.actions.delete'
- ];
-
- /**
- * @ngdoc service
- * @ngname horizon.dashboard.project.lbaasv2.healthmonitors.actions.rowActions
- *
- * @description
- * Provides the service for the health monitor row actions.
- *
- * @param gettext The horizon gettext function for translation.
- * @param loadBalancersService The LBaaS v2 load balancers service.
- * @param editService The LBaaS v2 health monitor edit service.
- * @param deleteService The LBaaS v2 health monitor delete service.
- * @returns Health monitor row actions service object.
- */
-
- function rowActions(gettext, loadBalancersService, editService, deleteService) {
- var loadBalancerIsActionable, loadbalancerId, listenerId, poolId;
-
- var service = {
- actions: actions,
- init: init
- };
-
- return service;
-
- ///////////////
-
- function init(_loadbalancerId_, _listenerId_, _poolId_) {
- loadbalancerId = _loadbalancerId_;
- listenerId = _listenerId_;
- poolId = _poolId_;
- loadBalancerIsActionable = loadBalancersService.isActionable(loadbalancerId);
- return service;
- }
-
- function actions() {
- return [{
- service: editService.init(loadBalancerIsActionable).edit,
- template: {
- text: gettext('Edit')
- }
- },{
- service: deleteService.init(loadbalancerId, listenerId, poolId, loadBalancerIsActionable),
- template: {
- text: gettext('Delete Health Monitor'),
- type: 'delete'
- }
- }];
- }
- }
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/row-actions.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/row-actions.service.spec.js
deleted file mode 100644
index 31abe592..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/row-actions.service.spec.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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 Health Monitor Row Actions Service', function() {
- var actions;
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
- beforeEach(module('horizon.dashboard.project.lbaasv2'));
-
- beforeEach(inject(function ($injector) {
- var rowActionsService = $injector.get(
- 'horizon.dashboard.project.lbaasv2.healthmonitors.actions.rowActions');
- actions = rowActionsService.init('1', '2', '3').actions();
- var loadbalancerService = $injector.get(
- 'horizon.dashboard.project.lbaasv2.loadbalancers.service');
- spyOn(loadbalancerService, 'isActionable').and.returnValue(true);
- }));
-
- it('should define correct table row actions', function() {
- expect(actions.length).toBe(2);
- expect(actions[0].template.text).toBe('Edit');
- expect(actions[1].template.text).toBe('Delete Health Monitor');
- });
-
- it('should have the "allowed" and "perform" functions', function() {
- actions.forEach(function(action) {
- expect(action.service.allowed).toBeDefined();
- expect(action.service.perform).toBeDefined();
- });
- });
-
- });
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.controller.js
deleted file mode 100644
index 908b4618..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.controller.js
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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.healthmonitors')
- .controller('HealthMonitorDetailController', HealthMonitorDetailController);
-
- HealthMonitorDetailController.$inject = [
- 'horizon.app.core.openstack-service-api.lbaasv2',
- 'horizon.dashboard.project.lbaasv2.healthmonitors.actions.rowActions',
- '$routeParams',
- '$q'
- ];
-
- /**
- * @ngdoc controller
- * @name HealthMonitorDetailController
- *
- * @description
- * Controller for the LBaaS v2 health monitor detail page.
- *
- * @param api The LBaaS v2 API service.
- * @param rowActions The LBaaS v2 health monitor row actions service.
- * @param $routeParams The angular $routeParams service.
- * @param $q The angular service for promises.
- * @returns undefined
- */
-
- function HealthMonitorDetailController(api, rowActions, $routeParams, $q) {
- var ctrl = this;
-
- ctrl.loading = true;
- ctrl.error = false;
- ctrl.actions = rowActions.init($routeParams.loadbalancerId,
- $routeParams.listenerId,
- $routeParams.poolId).actions;
-
- init();
-
- ////////////////////////////////
-
- function init() {
- ctrl.healthmonitor = null;
- ctrl.pool = null;
- ctrl.listener = null;
- ctrl.loadbalancer = null;
- ctrl.loading = true;
- ctrl.error = false;
- $q.all([
- api.getHealthMonitor($routeParams.healthmonitorId)
- .then(success('healthmonitor'), fail('healthmonitor')),
- api.getPool($routeParams.poolId)
- .then(success('pool'), fail('pool')),
- api.getListener($routeParams.listenerId)
- .then(success('listener'), fail('listener')),
- api.getLoadBalancer($routeParams.loadbalancerId)
- .then(success('loadbalancer'), fail('loadbalancer'))
- ]).then(postInit, initError);
- }
-
- function success(property) {
- return angular.bind(null, function setProp(property, response) {
- ctrl[property] = response.data;
- }, property);
- }
-
- function fail(property) {
- return angular.bind(null, function setProp(property, error) {
- ctrl[property] = null;
- throw error;
- }, property);
- }
-
- function postInit() {
- ctrl.loading = false;
- }
-
- function initError() {
- ctrl.loading = false;
- ctrl.error = true;
- }
-
- }
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.controller.spec.js
deleted file mode 100644
index fd02239d..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.controller.spec.js
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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 Healthmonitor Detail Controller', function() {
- var lbaasv2API, $controller, apiFail, qAllFail;
-
- function fakePromise(data, reject) {
- return {
- then: function(success, fail) {
- if (reject) {
- fail();
- } else {
- success({ data: data });
- }
- return fakePromise();
- }
- };
- }
-
- function fakeAPI() {
- return fakePromise('foo', apiFail);
- }
-
- function loadbalancerAPI() {
- return fakePromise({ provisioning_status: 'ACTIVE' });
- }
-
- function qAll() {
- return fakePromise(null, qAllFail);
- }
-
- function createController() {
- return $controller('HealthMonitorDetailController', {
- $routeParams: {
- loadbalancerId: 'loadbalancerId',
- listenerId: 'listenerId',
- poolId: 'poolId',
- healthmonitorId: 'healthmonitorId'
- }
- });
- }
-
- ///////////////////////
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
- beforeEach(module('horizon.dashboard.project.lbaasv2'));
-
- beforeEach(module(function($provide) {
- apiFail = false;
- qAllFail = false;
-
- $provide.value('$q', { all: qAll });
- }));
-
- beforeEach(inject(function($injector) {
- lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
- spyOn(lbaasv2API, 'getHealthMonitor').and.callFake(fakeAPI);
- spyOn(lbaasv2API, 'getPool').and.callFake(fakeAPI);
- spyOn(lbaasv2API, 'getListener').and.callFake(fakeAPI);
- spyOn(lbaasv2API, 'getLoadBalancer').and.callFake(loadbalancerAPI);
- $controller = $injector.get('$controller');
- }));
-
- it('should invoke lbaasv2 apis', function() {
- var ctrl = createController();
- expect(lbaasv2API.getHealthMonitor).toHaveBeenCalledWith('healthmonitorId');
- expect(lbaasv2API.getPool).toHaveBeenCalledWith('poolId');
- expect(lbaasv2API.getListener).toHaveBeenCalledWith('listenerId');
- expect(lbaasv2API.getLoadBalancer).toHaveBeenCalledWith('loadbalancerId');
- expect(ctrl.loadbalancer).toEqual({ provisioning_status: 'ACTIVE' });
- expect(ctrl.listener).toBe('foo');
- expect(ctrl.pool).toBe('foo');
- expect(ctrl.healthmonitor).toBe('foo');
- });
-
- it('should throw error on API fail', function() {
- apiFail = true;
- var init = function() {
- createController();
- };
- expect(init).toThrow();
- });
-
- it('should set error state if any APIs fail', function() {
- qAllFail = true;
- var ctrl = createController();
- expect(ctrl.loading).toBe(false);
- expect(ctrl.error).toBe(true);
- });
-
- });
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.html
deleted file mode 100644
index a199a712..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.html
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
-
- - Type
- - {$ ::ctrl.healthmonitor.type $}
- - Delay
- - {$ ::ctrl.healthmonitor.delay $}
- - Max Retries
- - {$ ::ctrl.healthmonitor.max_retries $}
- - Max Retries Down
- - {$ ::ctrl.healthmonitor.max_retries_down $}
- - Timeout
- - {$ ::ctrl.healthmonitor.timeout $}
- - HTTP Method
- - {$ ::ctrl.healthmonitor.http_method $}
- - Expected Codes
- - {$ ::ctrl.healthmonitor.expected_codes $}
- - URL Path
- - {$ ::ctrl.healthmonitor.url_path $}
- - Admin State Up
- - {$ ctrl.healthmonitor.admin_state_up | yesno $}
- - Monitor ID
- - {$ ::ctrl.healthmonitor.id $}
- - Project ID
- - {$ ::ctrl.healthmonitor.project_id $}
- - Created At
- - {$ ::ctrl.healthmonitor.created_at $}
- - Updated At
- - {$ ::ctrl.healthmonitor.updated_at $}
-
-
-
-
-
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
new file mode 100644
index 00000000..ed45dd3a
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.js
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
+ *
+ * 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.healthmonitors')
+ .controller('HealthMonitorDetailController', HealthMonitorDetailController);
+
+ HealthMonitorDetailController.$inject = [
+ 'loadbalancer',
+ 'listener',
+ 'pool',
+ 'healthmonitor',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
+ 'horizon.dashboard.project.lbaasv2.healthmonitors.resourceType',
+ 'horizon.framework.conf.resource-type-registry.service',
+ 'horizon.framework.widgets.modal-wait-spinner.service',
+ '$q'
+ ];
+
+ /**
+ * @ngdoc controller
+ * @name HealthMonitorDetailController
+ *
+ * @description
+ * Controller for the LBaaS v2 health monitor detail page.
+ *
+ * @param loadbalancer The loadbalancer object.
+ * @param listener The listener object.
+ * @param pool The pool object.
+ * @param healthmonitor The health monitor object.
+ * @param loadBalancersService The LBaaS v2 load balancers service.
+ * @param resourceType The health monitor resource type.
+ * @param typeRegistry The horizon resource type registry service.
+ * @param spinnerService The horizon modal wait spinner service.
+ * @param $q The angular service for promises.
+ *
+ * @returns undefined
+ */
+
+ function HealthMonitorDetailController(
+ loadbalancer, listener, pool, healthmonitor, loadBalancersService,
+ resourceType, typeRegistry, spinnerService, $q
+ ) {
+ var ctrl = this;
+
+ ctrl.operatingStatus = loadBalancersService.operatingStatus;
+ ctrl.provisioningStatus = loadBalancersService.provisioningStatus;
+ ctrl.loadbalancer = loadbalancer;
+ ctrl.listener = listener;
+ ctrl.pool = pool;
+ ctrl.healthmonitor = healthmonitor;
+ ctrl.resourceType = typeRegistry.getResourceType(resourceType);
+ ctrl.context = {};
+ ctrl.context.identifier = ctrl.resourceType.parsePath(ctrl.healthmonitor.id);
+
+ ctrl.resultHandler = actionResultHandler;
+
+ function actionResultHandler(returnValue) {
+ return $q.when(returnValue, actionSuccessHandler);
+ }
+
+ function loadData(response) {
+ spinnerService.hideModalSpinner();
+ ctrl.showDetails = true;
+ ctrl.resourceType.initActions();
+ ctrl.healthmonitor = response.data;
+ ctrl.healthmonitor.loadbalancerId = ctrl.loadbalancer.id;
+ ctrl.healthmonitor.listenerId = ctrl.listener.id;
+ ctrl.healthmonitor.poolId = ctrl.pool.id;
+ }
+
+ function actionSuccessHandler(result) {
+ // The action has completed (for whatever "complete" means to that
+ // action. Notice the view doesn't really need to know the semantics of the
+ // particular action because the actions return data in a standard form.
+ // That return includes the id and type of each created, updated, deleted
+ // and failed item.
+ // Currently just refreshes the display each time.
+ if (result) {
+ spinnerService.showModalSpinner(gettext('Please Wait'));
+ ctrl.showDetails = false;
+ ctrl.context.loadPromise = ctrl.resourceType.load(ctrl.context.identifier);
+ ctrl.context.loadPromise.then(loadData);
+ }
+ }
+ }
+
+})();
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
new file mode 100644
index 00000000..a4da6718
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.spec.js
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
+ *
+ * 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 HealthMonitor Detail Controller', function() {
+ var deferred, service, ctrl, scope, $timeout, $q, actionResultService;
+
+ ///////////////////////
+
+ beforeEach(module('horizon.dashboard.project.lbaasv2'));
+
+ beforeEach(module(function($provide) {
+ $provide.value('$uibModal', {});
+ }));
+
+ beforeEach(inject(function($controller, $rootScope, _$q_, _$timeout_) {
+ $q = _$q_;
+ deferred = $q.defer();
+ service = {
+ getResourceType: function() {
+ return {
+ load: function() { return deferred.promise; },
+ parsePath: function() { return 'my-context'; },
+ itemName: function() { return 'A name'; },
+ initActions: angular.noop
+ };
+ },
+ getDefaultDetailsTemplateUrl: angular.noop
+ };
+ actionResultService = {
+ getIdsOfType: function() { return []; }
+ };
+ $timeout = _$timeout_;
+ scope = $rootScope.$new();
+ ctrl = $controller('HealthMonitorDetailController', {
+ $scope: scope,
+ loadbalancer: { id: '123' },
+ listener: { id: '123' },
+ 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
+ }
+ });
+ }));
+
+ it('should create a controller', function() {
+ expect(ctrl).toBeDefined();
+ expect(ctrl.loadbalancer).toBeDefined();
+ expect(ctrl.listener).toBeDefined();
+ expect(ctrl.pool).toBeDefined();
+ expect(ctrl.healthmonitor).toBeDefined();
+ });
+
+ describe('resultHandler', function() {
+
+ it('handles empty results', function() {
+ var result = $q.defer();
+ result.resolve({});
+ ctrl.resultHandler(result.promise);
+ $timeout.flush();
+ expect(ctrl.showDetails).not.toBe(true);
+ });
+
+ it('handles falsy results', function() {
+ var result = $q.defer();
+ result.resolve(false);
+ ctrl.resultHandler(result.promise);
+ $timeout.flush();
+ expect(ctrl.showDetails).not.toBe(true);
+ });
+
+ it('handles matched results', function() {
+ spyOn(actionResultService, 'getIdsOfType').and.returnValue([1, 2, 3]);
+ var result = $q.defer();
+ result.resolve({some: 'thing'});
+ ctrl.resultHandler(result.promise);
+ deferred.resolve({data: {some: 'data'}});
+ $timeout.flush();
+ expect(ctrl.showDetails).toBe(true);
+ });
+
+ });
+ });
+
+})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.html
new file mode 100644
index 00000000..81df2083
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.html
@@ -0,0 +1,53 @@
+
+
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/drawer.html b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/drawer.html
new file mode 100644
index 00000000..986478df
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/drawer.html
@@ -0,0 +1,10 @@
+
+
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/healthmonitors.module.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/healthmonitors.module.js
index 0a7d50fc..eb44d023 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/healthmonitors.module.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/healthmonitors.module.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -26,6 +27,138 @@
*/
angular
- .module('horizon.dashboard.project.lbaasv2.healthmonitors', []);
+ .module('horizon.dashboard.project.lbaasv2.healthmonitors', [])
+ .constant('horizon.dashboard.project.lbaasv2.healthmonitors.resourceType',
+ 'OS::Octavia::HealthMonitor')
+ .run(run);
+
+ run.$inject = [
+ 'horizon.framework.conf.resource-type-registry.service',
+ 'horizon.dashboard.project.lbaasv2.basePath',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
+ 'horizon.dashboard.project.lbaasv2.healthmonitors.actions.create',
+ 'horizon.dashboard.project.lbaasv2.healthmonitors.actions.edit',
+ 'horizon.dashboard.project.lbaasv2.healthmonitors.actions.delete',
+ 'horizon.dashboard.project.lbaasv2.healthmonitors.resourceType'
+ ];
+
+ function run(
+ registry,
+ basePath,
+ loadBalancerService,
+ createService,
+ editService,
+ deleteService,
+ resourceType
+ ) {
+ var healthMonitorResourceType = registry.getResourceType(resourceType);
+
+ healthMonitorResourceType
+ .setNames(gettext('Health Monitor'), gettext('Health Monitors'))
+ .setSummaryTemplateUrl(basePath + 'healthmonitors/details/drawer.html')
+ .setProperties(healthMonitorProperties(loadBalancerService))
+ .setListFunction(loadBalancerService.getHealthMonitorsPromise)
+ .setLoadFunction(loadBalancerService.getHealthMonitorPromise)
+ .tableColumns
+ .append({
+ id: 'name',
+ priority: 1,
+ sortDefault: true,
+ urlFunction: loadBalancerService.getHealthMonitorDetailsPath
+ })
+ .append({
+ id: 'type',
+ priority: 1
+ })
+ .append({
+ id: 'operating_status',
+ priority: 1
+ })
+ .append({
+ id: 'provisioning_status',
+ priority: 1
+ })
+ .append({
+ id: 'admin_state_up',
+ priority: 1
+ });
+
+ healthMonitorResourceType.itemActions
+ .append({
+ id: 'healthMonitorEdit',
+ service: editService,
+ template: {
+ text: gettext('Edit Health Monitor')
+ }
+ })
+ .append({
+ id: 'healthMonitorDelete',
+ service: deleteService,
+ template: {
+ text: gettext('Delete Health Monitor'),
+ type: 'delete'
+ }
+ });
+
+ healthMonitorResourceType.globalActions
+ .append({
+ id: 'healthMonitorCreate',
+ service: createService,
+ template: {
+ type: 'create',
+ text: gettext('Create Health Monitor')
+ }
+ });
+
+ healthMonitorResourceType.batchActions
+ .append({
+ id: 'healthMonitorBatchDelete',
+ service: deleteService,
+ template: {
+ text: gettext('Delete Health Monitors'),
+ type: 'delete-selected'
+ }
+ });
+ }
+
+ function healthMonitorProperties(loadBalancerService) {
+ return {
+ id: gettext('ID'),
+ name: {
+ label: gettext('Name'),
+ filters: ['noName']
+ },
+ provisioning_status: {
+ label: gettext('Provisioning Status'),
+ values: loadBalancerService.provisioningStatus
+ },
+ operating_status: {
+ label: gettext('Operating Status'),
+ values: loadBalancerService.operatingStatus
+ },
+ admin_state_up: {
+ label: gettext('Admin State Up'),
+ filters: ['yesno']
+ },
+ type: gettext('Type'),
+ delay: gettext('Delay'),
+ timeout: gettext('Timeout'),
+ max_retries: gettext('Max Retries'),
+ max_retries_down: gettext('Max Retries Down'),
+ http_method: gettext('HTTP Method'),
+ url_path: gettext('URL Path'),
+ expected_codes: gettext('Expected Codes'),
+ project_id: gettext('Project ID'),
+ created_at: {
+ label: gettext('Created At'),
+ filters: ['noValue']
+ },
+ updated_at: {
+ label: gettext('Updated At'),
+ filters: ['noValue']
+ },
+ pools: gettext('Pools')
+ };
+ }
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/healthmonitors.module.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/healthmonitors.module.spec.js
index 63198d6a..d9fc0a6d 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/healthmonitors.module.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/healthmonitors.module.spec.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -22,4 +23,46 @@
});
});
+ describe('LBaaS v2 Healthmonitors Registry', function () {
+ var registry, resourceType;
+
+ beforeEach(module('horizon.dashboard.project.lbaasv2'));
+
+ beforeEach(inject(function($injector) {
+ resourceType = $injector.get('horizon.dashboard.project.lbaasv2.healthmonitors.resourceType');
+ registry = $injector.get('horizon.framework.conf.resource-type-registry.service');
+ }));
+
+ it('should define resourceType', function () {
+ expect(resourceType).toBeDefined();
+ });
+
+ it('should register item actions', function () {
+ var actions = registry.getResourceType(resourceType).itemActions;
+ expect(actionHasId(actions, 'healthMonitorEdit')).toBe(true);
+ expect(actionHasId(actions, 'healthMonitorDelete')).toBe(true);
+ });
+
+ it('should register global actions', function () {
+ var actions = registry.getResourceType(resourceType).globalActions;
+ expect(actionHasId(actions, 'healthMonitorCreate')).toBe(true);
+ });
+
+ it('should register batch actions', function () {
+ var actions = registry.getResourceType(resourceType).batchActions;
+ expect(actionHasId(actions, 'healthMonitorBatchDelete')).toBe(true);
+ });
+
+ function actionHasId(list, value) {
+ return list.filter(matchesId).length === 1;
+
+ function matchesId(action) {
+ if (action.id === value) {
+ return true;
+ }
+ }
+ }
+
+ });
+
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js b/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js
index 4026802f..83de477c 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js
@@ -1,5 +1,6 @@
/*
* Copyright 2015 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -25,12 +26,15 @@
angular
.module('horizon.dashboard.project.lbaasv2', [
- 'ngRoute',
'horizon.dashboard.project.lbaasv2.loadbalancers',
'horizon.dashboard.project.lbaasv2.listeners',
'horizon.dashboard.project.lbaasv2.pools',
'horizon.dashboard.project.lbaasv2.members',
- 'horizon.dashboard.project.lbaasv2.healthmonitors'
+ 'horizon.dashboard.project.lbaasv2.healthmonitors',
+ 'horizon.framework.conf',
+ 'horizon.framework.widgets',
+ 'horizon.framework.util',
+ 'horizon.app.core'
])
.config(config)
.constant('horizon.dashboard.project.lbaasv2.patterns', {
@@ -45,7 +49,12 @@
})
.constant('horizon.dashboard.project.lbaasv2.popovers', {
ipAddresses: ''
- });
+ })
+ .run(['$rootScope', '$location', function ($rootScope, $location) {
+ $rootScope.$on('$routeChangeError', function() {
+ $location.path('project/load_balancer');
+ });
+ }]);
config.$inject = [
'$provide',
@@ -65,22 +74,212 @@
$routeProvider
.when(loadbalancers, {
- templateUrl: basePath + 'loadbalancers/table.html'
+ templateUrl: basePath + 'loadbalancers/panel.html'
})
.when(loadbalancers + '/:loadbalancerId', {
- templateUrl: basePath + 'loadbalancers/detail.html'
+ templateUrl: basePath + 'loadbalancers/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;
+ }
+ );
+ }
+ ]
+ },
+ controller: 'LoadBalancerDetailController',
+ controllerAs: 'ctrl'
})
.when(listener, {
- templateUrl: basePath + 'listeners/detail.html'
+ templateUrl: basePath + 'listeners/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: [
+ '$route',
+ 'horizon.app.core.openstack-service-api.lbaasv2',
+ function($route, api) {
+ return api.getListener($route.current.params.listenerId).then(
+ function success(response) {
+ response.data.loadbalancerId = $route.current.params.loadbalancerId;
+ return response.data;
+ }
+ );
+ }
+ ]
+ },
+ controller: 'ListenerDetailController',
+ controllerAs: 'ctrl'
})
.when(pool, {
- templateUrl: basePath + 'pools/detail.html'
+ 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: [
+ '$route',
+ 'horizon.app.core.openstack-service-api.lbaasv2',
+ function($route, api) {
+ return api.getListener($route.current.params.listenerId).then(
+ function success(response) {
+ return response.data;
+ }
+ );
+ }
+ ],
+ 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(member, {
- templateUrl: basePath + 'members/detail.html'
+ 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: [
+ '$route',
+ 'horizon.app.core.openstack-service-api.lbaasv2',
+ function($route, api) {
+ return api.getListener($route.current.params.listenerId).then(
+ function success(response) {
+ return response.data;
+ }
+ );
+ }
+ ],
+ 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(healthmonitor, {
- templateUrl: basePath + 'healthmonitors/detail.html'
+ 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: [
+ '$route',
+ 'horizon.app.core.openstack-service-api.lbaasv2',
+ function($route, api) {
+ return api.getListener($route.current.params.listenerId).then(
+ function success(response) {
+ return response.data;
+ }
+ );
+ }
+ ],
+ 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 5cbb7bec..86f8149a 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js
@@ -1,5 +1,6 @@
/*
* Copyright 2015 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -104,43 +105,270 @@
inject();
});
- it('should route URLs', function () {
+ it('should route to loadbalancer panel', function () {
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 routes = [[
loadbalancers, {
- templateUrl: basePath + 'loadbalancers/table.html'
- }
- ], [
- loadbalancers + '/:loadbalancerId', {
- templateUrl: basePath + 'loadbalancers/detail.html'
- }
- ], [
- listener, {
- templateUrl: basePath + 'listeners/detail.html'
- }
- ], [
- pool, {
- templateUrl: basePath + 'pools/detail.html'
- }
- ], [
- member, {
- templateUrl: basePath + 'members/detail.html'
- }
- ], [
- healthmonitor, {
- templateUrl: basePath + 'healthmonitors/detail.html'
+ templateUrl: basePath + 'loadbalancers/panel.html'
}
]];
- expect($routeProvider.when.calls.count()).toBe(6);
- angular.forEach($routeProvider.when.calls.all(), function(call, i) {
- expect(call.args).toEqual(routes[i]);
+ routes.forEach(function(route) {
+ expect($routeProvider.when).toHaveBeenCalledWith(route[0], route[1]);
});
});
+
+ it('should route resolved loadbalancer 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: {}}});
+ }
+ };
+ }
+
+ var lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
+ spyOn(lbaasv2API, 'getLoadBalancer').and.callFake(loadbalancerAPI);
+ inject(function($route, $location, $rootScope, $httpBackend) {
+ $httpBackend.expectGET(
+ '/static/dashboard/project/lbaasv2/loadbalancers/details/detail.html'
+ ).respond({});
+ $location.path('/project/load_balancer/1');
+ $rootScope.$digest();
+ expect($route.current).toBeDefined();
+
+ });
+ }));
+
+ it('should route resolved listener 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 listenerAPI() {
+ var listener = { provisioning_status: 'ACTIVE' };
+ return {
+ success: function(callback) {
+ callback(listener);
+ },
+ 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, 'getListener').and.callFake(listenerAPI);
+ inject(function($route, $location, $rootScope, $httpBackend) {
+ $httpBackend.expectGET(
+ '/static/dashboard/project/lbaasv2/listeners/details/detail.html'
+ ).respond({});
+ $location.path('/project/load_balancer/1/listeners/2');
+ $rootScope.$digest();
+ expect($route.current).toBeDefined();
+ });
+ }));
+
+ it('should route resolved 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 listenerAPI() {
+ var listener = { provisioning_status: 'ACTIVE' };
+ return {
+ success: function(callback) {
+ callback(listener);
+ },
+ then: function(callback) {
+ callback({ data: { id: 1}});
+ }
+ };
+ }
+
+ 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, 'getListener').and.callFake(listenerAPI);
+ 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/listeners/2/pools/3');
+ $rootScope.$digest();
+ expect($route.current).toBeDefined();
+ });
+ }));
+
+ it('should route resolved 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 listenerAPI() {
+ var listener = { provisioning_status: 'ACTIVE' };
+ return {
+ success: function(callback) {
+ callback(listener);
+ },
+ then: function(callback) {
+ callback({ data: { id: 1}});
+ }
+ };
+ }
+
+ 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, 'getListener').and.callFake(listenerAPI);
+ 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/listeners/2/pools/3/members/4');
+ $rootScope.$digest();
+ expect($route.current).toBeDefined();
+ });
+ }));
+
+ it('should route resolved 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 listenerAPI() {
+ var listener = { provisioning_status: 'ACTIVE' };
+ return {
+ success: function(callback) {
+ callback(listener);
+ },
+ then: function(callback) {
+ callback({ data: { id: 1}});
+ }
+ };
+ }
+
+ 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, 'getListener').and.callFake(listenerAPI);
+ 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/listeners/2/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();
+ $rootScope.$emit('$routeChangeError', null, null, null, 'routeChangeError');
+ expect($location.path).toHaveBeenCalledWith('project/load_balancer');
+ })
+ );
+
});
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.scss b/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.scss
index e20e7d64..408e3ab2 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.scss
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.scss
@@ -1,5 +1,6 @@
/*
* Copyright 2015 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -74,9 +75,8 @@
}
}
-/* Progress indicator while data is loading */
-[table-status],
-detail-status {
+/* Progress indicator in the table while items are loading */
+[table-status] {
.progress {
margin: 0px auto;
width: 25%;
@@ -86,12 +86,9 @@ detail-status {
}
}
}
-detail-status {
- .progress {
- margin-top: 25vh;
- }
- .error-actions {
- text-align: center;
+
+.octavia-tabset {
+ .tab-content {
margin-top: 10px;
}
}
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/batch-actions.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/batch-actions.service.js
deleted file mode 100644
index 5d3b1537..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/batch-actions.service.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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.listeners')
- .factory('horizon.dashboard.project.lbaasv2.listeners.actions.batchActions',
- tableBatchActions);
-
- tableBatchActions.$inject = [
- '$q',
- '$location',
- 'horizon.dashboard.project.lbaasv2.workflow.modal',
- 'horizon.app.core.openstack-service-api.policy',
- 'horizon.framework.util.i18n.gettext',
- 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
- 'horizon.dashboard.project.lbaasv2.listeners.actions.delete'
- ];
-
- /**
- * @ngdoc service
- * @ngname horizon.dashboard.project.lbaasv2.listeners.actions.batchActions
- *
- * @description
- * Provides the service for the Listeners table batch actions.
- *
- * @param $q The angular service for promises.
- * @param $location The angular $location service.
- * @param workflowModal The LBaaS workflow modal service.
- * @param policy The horizon policy service.
- * @param gettext The horizon gettext function for translation.
- * @param loadBalancersService The LBaaS v2 load balancers service.
- * @param deleteService The LBaaS v2 listeners delete service.
- * @returns Listeners table batch actions service object.
- */
-
- function tableBatchActions(
- $q, $location, workflowModal, policy, gettext, loadBalancersService, deleteService
- ) {
- var loadBalancerIsActionable, loadBalancerId;
-
- var create = workflowModal.init({
- controller: 'CreateListenerWizardController',
- message: gettext('A new listener is being created.'),
- handle: onCreate,
- allowed: canCreate
- });
-
- var service = {
- actions: actions,
- init: init
- };
-
- return service;
-
- ///////////////
-
- function init(_loadBalancerId_) {
- loadBalancerId = _loadBalancerId_;
- loadBalancerIsActionable = loadBalancersService.isActionable(loadBalancerId);
- return service;
- }
-
- function actions() {
- return [{
- service: create,
- template: {
- type: 'create',
- text: gettext('Create Listener')
- }
- },{
- service: deleteService.init(loadBalancerId, loadBalancerIsActionable),
- template: {
- text: gettext('Delete Listeners'),
- type: 'delete-selected'
- }
- }];
- }
-
- function canCreate() {
- return $q.all([
- loadBalancerIsActionable,
- policy.ifAllowed({ rules: [['neutron', 'create_listener']] })
- ]);
- }
-
- function onCreate(response) {
- var id = response.data.id;
- $location.path('project/load_balancer/' + loadBalancerId + '/listeners/' + id);
- }
- }
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/batch-actions.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/batch-actions.service.spec.js
deleted file mode 100644
index 35ec5a62..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/batch-actions.service.spec.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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 Listeners Table Batch Actions Service', function() {
- var $location, actions, policy, $scope, $q;
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
- beforeEach(module('horizon.dashboard.project.lbaasv2'));
-
- beforeEach(module(function($provide) {
- var response = {
- data: {
- id: '5678'
- }
- };
- var modal = {
- open: function() {
- return {
- result: {
- then: function(func) {
- func(response);
- }
- }
- };
- }
- };
- $provide.value('$uibModal', modal);
- $provide.value('horizon.dashboard.project.lbaasv2.loadbalancers.service', {
- isActionable: function() {
- return $q.when();
- }
- });
- $provide.value('horizon.app.core.openstack-service-api.policy', {
- ifAllowed: function() {
- return $q.when();
- }
- });
- }));
-
- beforeEach(inject(function ($injector) {
- $location = $injector.get('$location');
- $scope = $injector.get('$rootScope').$new();
- $q = $injector.get('$q');
- policy = $injector.get('horizon.app.core.openstack-service-api.policy');
- var batchActionsService = $injector.get(
- 'horizon.dashboard.project.lbaasv2.listeners.actions.batchActions');
- actions = batchActionsService.init('1234').actions();
- $scope.$apply();
- }));
-
- it('should define correct table batch actions', function() {
- expect(actions.length).toBe(2);
- expect(actions[0].template.text).toBe('Create Listener');
- expect(actions[1].template.text).toBe('Delete Listeners');
- });
-
- 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 check policy to allow creating a listener', function() {
- spyOn(policy, 'ifAllowed').and.callThrough();
-
- var promise = actions[0].service.allowed();
- var allowed;
- promise.then(function() {
- allowed = true;
- }, function() {
- allowed = false;
- });
- $scope.$apply();
-
- expect(allowed).toBe(true);
- expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'create_listener']]});
- });
-
- it('should redirect after create', function() {
- spyOn($location, 'path').and.callThrough();
- actions[0].service.perform();
- expect($location.path).toHaveBeenCalledWith('project/load_balancer/1234/listeners/5678');
- });
-
- });
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/create/create.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/create/create.service.js
new file mode 100644
index 00000000..22245452
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/create/create.service.js
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2017 Walmart.
+ *
+ * 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.listeners')
+ .factory('horizon.dashboard.project.lbaasv2.listeners.actions.create',
+ createService);
+
+ createService.$inject = [
+ 'horizon.dashboard.project.lbaasv2.listeners.resourceType',
+ 'horizon.framework.util.actions.action-result.service',
+ 'horizon.dashboard.project.lbaasv2.workflow.modal',
+ 'horizon.app.core.openstack-service-api.policy',
+ 'horizon.framework.util.i18n.gettext'
+ ];
+
+ /**
+ * @ngdoc service
+ * @ngname horizon.dashboard.project.lbaasv2.listeners.actions.batchActions
+ *
+ * @description
+ * Provides the service for the Listeners creation.
+ *
+ * @param resourceType The listener resource type.
+ * @param actionResultService The horizon action result service.
+ * @param workflowModal The LBaaS workflow modal service.
+ * @param policy The horizon policy service.
+ * @param gettext The horizon gettext function for translation.
+ *
+ * @returns Listeners create service object.
+ */
+
+ function createService(
+ resourceType, actionResultService, workflowModal, policy, gettext
+ ) {
+ return workflowModal.init({
+ controller: 'CreateListenerWizardController',
+ message: gettext('A new listener is being created.'),
+ handle: handle,
+ allowed: allowed
+ });
+
+ function allowed() {
+ return policy.ifAllowed({ rules: [['neutron', 'create_listener']] });
+ }
+
+ function handle(response) {
+ return actionResultService.getActionResult()
+ .created(resourceType, response.data.id)
+ .result;
+ }
+ }
+
+})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/create/create.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/create/create.service.spec.js
new file mode 100644
index 00000000..b24c078d
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/create/create.service.spec.js
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2017 Walmart.
+ *
+ * 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 Create Listener Action Service', function() {
+ var policy, service;
+
+ beforeEach(module('horizon.dashboard.project.lbaasv2'));
+
+ beforeEach(module(function($provide) {
+ $provide.value('$modal', {
+ open: function() {
+ return {
+ result: {
+ then: function(func) {
+ func({ data: { id: 'listener1' } });
+ }
+ }
+ };
+ }
+ });
+ }));
+
+ beforeEach(inject(function ($injector) {
+ policy = $injector.get('horizon.app.core.openstack-service-api.policy');
+ service = $injector.get('horizon.dashboard.project.lbaasv2.listeners.actions.create');
+ }));
+
+ it('should check policy to allow creating a listener', function() {
+ spyOn(policy, 'ifAllowed').and.returnValue(true);
+ expect(service.allowed()).toBe(true);
+ expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'create_listener']]});
+ });
+
+ it('should handle the action result properly', function() {
+ var result = service.handle({data: {id: 1}});
+ expect(result.created[0].id).toBe(1);
+ });
+
+ });
+})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/delete/delete.action.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/delete/delete.action.service.js
index fba8caf8..8d502720 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/delete/delete.action.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/delete/delete.action.service.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -21,9 +22,10 @@
.factory('horizon.dashboard.project.lbaasv2.listeners.actions.delete', deleteService);
deleteService.$inject = [
+ 'horizon.dashboard.project.lbaasv2.listeners.resourceType',
+ 'horizon.framework.util.actions.action-result.service',
'$q',
'$location',
- '$route',
'horizon.framework.widgets.modal.deleteModalService',
'horizon.app.core.openstack-service-api.lbaasv2',
'horizon.app.core.openstack-service-api.policy',
@@ -35,26 +37,31 @@
/**
* @ngDoc factory
* @name horizon.dashboard.project.lbaasv2.listeners.actions.deleteService
+ *
* @description
* Brings up the delete listeners confirmation modal dialog.
* On submit, deletes selected listeners.
* On cancel, does nothing.
+ *
+ * @param resourceType The listener resource type.
+ * @param actionResultService The horizon action result service.
* @param $q The angular service for promises.
* @param $location The angular $location service.
- * @param $route The angular $route service.
* @param deleteModal The horizon delete modal service.
* @param api The LBaaS v2 API service.
* @param policy The horizon policy service.
* @param toast The horizon message service.
* @param qExtensions Horizon extensions to the $q service.
* @param gettext The horizon gettext function for translation.
- * @returns The listeners table delete service.
+ *
+ * @returns The listeners delete service.
*/
function deleteService(
- $q, $location, $route, deleteModal, api, policy, toast, qExtensions, gettext
+ resourceType, actionResultService, $q, $location,
+ deleteModal, api, policy, toast, qExtensions, gettext
) {
- var loadbalancerId, statePromise;
+ var loadbalancerId, scope;
var notAllowedMessage = gettext('The following listeners will not be deleted ' +
'due to existing pools: %s.');
var context = {
@@ -74,54 +81,38 @@
var service = {
perform: perform,
- allowed: allowed,
- init: init
+ allowed: allowed
};
return service;
//////////////
- function init(_loadbalancerId_, _statePromise_) {
- loadbalancerId = _loadbalancerId_;
- statePromise = _statePromise_;
- return service;
+ function perform(items, _scope_) {
+ scope = _scope_;
+ var listeners = angular.isArray(items) ? items : [items];
+ listeners.map(function(item) {
+ loadbalancerId = item.loadbalancerId;
+ });
+ return qExtensions.allSettled(listeners.map(checkPermission)).then(afterCheck);
}
- function perform(items) {
- if (angular.isArray(items)) {
- qExtensions.allSettled(items.map(checkPermission)).then(afterCheck);
- } else {
- deleteModal.open({ $emit: actionComplete }, [items], context);
- }
- }
-
- function allowed(item) {
- var promises = [policy.ifAllowed({ rules: [['neutron', 'delete_listener']] }), statePromise];
- if (item) {
- promises.push(qExtensions.booleanAsPromise(!item.default_pool_id));
- }
- return $q.all(promises);
- }
-
- function deleteItem(id) {
- return api.deleteListener(id, true);
- }
-
- function actionComplete(eventType) {
- if (eventType === context.failedEvent) {
- // Action failed, reload the page
- $route.reload();
- } else {
- // If the user is on the listeners table then just reload the page, otherwise they
- // are on the details page and we return to the table.
- var regex = new RegExp('project\/load_balancer\/' + loadbalancerId + '(\/)?$');
- if (regex.test($location.path())) {
- $route.reload();
- } else {
- $location.path('project/load_balancer/' + loadbalancerId);
- }
+ function deleteResult(deleteModalResult) {
+ // To make the result of this action generically useful, reformat the return
+ // from the deleteModal into a standard form
+ var actionResult = actionResultService.getActionResult();
+ deleteModalResult.pass.forEach(function markDeleted(item) {
+ actionResult.deleted(resourceType, item.context.id);
+ });
+ deleteModalResult.fail.forEach(function markFailed(item) {
+ actionResult.failed(resourceType, item.context.id);
+ });
+
+ if (actionResult.result.failed.length === 0 && actionResult.result.deleted.length > 0) {
+ var path = 'project/load_balancer/' + loadbalancerId;
+ $location.path(path);
}
+ return actionResult.result;
}
function checkPermission(item) {
@@ -133,7 +124,7 @@
toast.add('error', getMessage(notAllowedMessage, result.fail));
}
if (result.pass.length > 0) {
- deleteModal.open({ $emit: actionComplete }, result.pass.map(getEntity), context);
+ return deleteModal.open(scope, result.pass.map(getEntity), context).then(deleteResult);
}
}
@@ -153,5 +144,12 @@
return result.context;
}
+ function allowed() {
+ return policy.ifAllowed({ rules: [['neutron', 'delete_listener']] });
+ }
+
+ function deleteItem(id) {
+ return api.deleteListener(id, true);
+ }
}
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/delete/delete.action.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/delete/delete.action.service.spec.js
index 43904dce..3fc763ab 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/delete/delete.action.service.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/delete/delete.action.service.spec.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -17,17 +18,11 @@
'use strict';
describe('LBaaS v2 Listeners Delete Service', function() {
- var service, policy, modal, lbaasv2Api, $scope, $route, $location, $q, toast, items, path;
+ var service, policy, modal, lbaasv2Api, $scope, $location, $q, toast, items, path;
function allowed(item) {
- spyOn(policy, 'ifAllowed').and.returnValue(makePromise());
- var promise = service.allowed(item);
- var allowed;
- promise.then(function() {
- allowed = true;
- }, function() {
- allowed = false;
- });
+ spyOn(policy, 'ifAllowed').and.returnValue(true);
+ var allowed = service.allowed(item);
$scope.$apply();
expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'delete_listener']]});
return allowed;
@@ -46,15 +41,19 @@
beforeEach(module('horizon.dashboard.project.lbaasv2'));
beforeEach(function() {
- items = [{ id: '1', name: 'First' },
- { id: '2', name: 'Second' }];
+ items = [{ id: '1', name: 'First', loadbalancerId: 1 },
+ { id: '2', name: 'Second', loadbalancerId: 1 }];
});
beforeEach(module(function($provide) {
$provide.value('$uibModal', {
open: function() {
return {
- result: makePromise()
+ result: {
+ then: function(func) {
+ return func({ data: { id: 'listener1' } });
+ }
+ }
};
}
});
@@ -75,12 +74,10 @@
lbaasv2Api = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
modal = $injector.get('horizon.framework.widgets.modal.deleteModalService');
$scope = $injector.get('$rootScope').$new();
- $route = $injector.get('$route');
$location = $injector.get('$location');
$q = $injector.get('$q');
toast = $injector.get('horizon.framework.widgets.toast.service');
service = $injector.get('horizon.dashboard.project.lbaasv2.listeners.actions.delete');
- service.init('1', makePromise());
}));
it('should have the "allowed" and "perform" functions', function() {
@@ -96,23 +93,14 @@
expect(allowed()).toBe(true);
});
- it('should not allow deleting a listener from load balancer in a PENDING state', function() {
- service.init('1', makePromise(true));
- expect(allowed()).toBe(false);
- });
-
- it('should not allow deleting a listener that has a default pool', function() {
- expect(allowed({default_pool_id: 'pool1'})).toBe(false);
- });
-
it('should open the delete modal', function() {
- spyOn(modal, 'open');
- service.perform(items[0]);
+ spyOn(modal, 'open').and.callThrough();
+ service.perform(items[0], $scope);
$scope.$apply();
expect(modal.open.calls.count()).toBe(1);
var args = modal.open.calls.argsFor(0);
expect(args.length).toBe(3);
- expect(args[0]).toEqual({ $emit: jasmine.any(Function) });
+ expect(args[0]).toEqual($scope);
expect(args[1]).toEqual([jasmine.objectContaining({ id: '1' })]);
expect(args[2]).toEqual(jasmine.objectContaining({
labels: jasmine.any(Object),
@@ -124,7 +112,7 @@
it('should pass function to modal that deletes listeners', function() {
spyOn(modal, 'open').and.callThrough();
spyOn(lbaasv2Api, 'deleteListener').and.callThrough();
- service.perform(items[0]);
+ service.perform(items[0], $scope);
$scope.$apply();
expect(lbaasv2Api.deleteListener.calls.count()).toBe(1);
expect(lbaasv2Api.deleteListener).toHaveBeenCalledWith('1', true);
@@ -135,7 +123,7 @@
spyOn(lbaasv2Api, 'deleteListener').and.returnValue(makePromise(true));
spyOn(toast, 'add');
items.splice(1, 1);
- service.perform(items);
+ service.perform(items, $scope);
$scope.$apply();
expect(modal.open).toHaveBeenCalled();
expect(lbaasv2Api.deleteListener.calls.count()).toBe(1);
@@ -143,19 +131,11 @@
'be deleted, possibly due to existing pools: First.');
});
- it('should reload table after delete', function() {
- path = 'project/load_balancer/1';
- spyOn($route, 'reload');
- service.perform(items);
- $scope.$apply();
- expect($route.reload).toHaveBeenCalled();
- });
-
it('should return to table after delete if on detail page', function() {
path = 'project/load_balancer/1/listeners/2';
spyOn($location, 'path');
spyOn(toast, 'add');
- service.perform(items[0]);
+ service.perform(items[0], $scope);
$scope.$apply();
expect($location.path).toHaveBeenCalledWith('project/load_balancer/1');
expect(toast.add).toHaveBeenCalledWith('success', 'Deleted listeners: First.');
@@ -166,7 +146,7 @@
spyOn(toast, 'add');
items[0].default_pool_id = 'pool1';
items[1].default_pool_id = 'pool2';
- service.perform(items);
+ service.perform(items, $scope);
$scope.$apply();
expect(modal.open).not.toHaveBeenCalled();
expect(toast.add).toHaveBeenCalledWith('error',
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/edit/edit.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/edit/edit.service.js
new file mode 100644
index 00000000..c59a6da4
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/edit/edit.service.js
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2017 Walmart.
+ *
+ * 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.listeners')
+ .factory('horizon.dashboard.project.lbaasv2.listeners.actions.edit',
+ editService);
+
+ editService.$inject = [
+ 'horizon.dashboard.project.lbaasv2.listeners.resourceType',
+ 'horizon.framework.util.actions.action-result.service',
+ 'horizon.dashboard.project.lbaasv2.workflow.modal',
+ 'horizon.app.core.openstack-service-api.policy',
+ 'horizon.framework.util.i18n.gettext'
+ ];
+
+ /**
+ * @ngdoc service
+ * @ngname horizon.dashboard.project.lbaasv2.listeners.actions.edit
+ *
+ * @description
+ * Provides the service for the Listener edit action.
+ *
+ * @param resourceType The listener resource type.
+ * @param actionResultService The horizon action result service.
+ * @param workflowModal The LBaaS workflow modal service.
+ * @param policy The horizon policy service.
+ * @param gettext The horizon gettext function for translation.
+ *
+ * @returns Listeners edit action service object.
+ */
+
+ function editService(
+ resourceType, actionResultService, workflowModal, policy, gettext
+ ) {
+ return workflowModal.init({
+ controller: 'EditListenerWizardController',
+ message: gettext('The listener has been updated.'),
+ handle: handle,
+ allowed: allowed
+ });
+
+ function allowed(/*item*/) {
+ return policy.ifAllowed({ rules: [['neutron', 'update_listener']] });
+ }
+
+ function handle(response) {
+ return actionResultService.getActionResult()
+ .updated(resourceType, response.config.data.listener.id)
+ .result;
+ }
+ }
+
+})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/edit/edit.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/edit/edit.service.spec.js
new file mode 100644
index 00000000..6ee839af
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/edit/edit.service.spec.js
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2017 Walmart.
+ *
+ * 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 Listener Action Service', function() {
+ var policy, service;
+
+ beforeEach(module('horizon.dashboard.project.lbaasv2'));
+
+ beforeEach(module(function($provide) {
+ $provide.value('$modal', {
+ open: function() {
+ return {
+ result: {
+ then: function(func) {
+ func({ data: { id: 'listener1' } });
+ }
+ }
+ };
+ }
+ });
+ }));
+
+ beforeEach(inject(function ($injector) {
+ policy = $injector.get('horizon.app.core.openstack-service-api.policy');
+ service = $injector.get('horizon.dashboard.project.lbaasv2.listeners.actions.edit');
+ }));
+
+ it('should check policy to allow editing a listener', function() {
+ spyOn(policy, 'ifAllowed').and.returnValue(true);
+ expect(service.allowed()).toBe(true);
+ expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'update_listener']]});
+ });
+
+ it('should handle the action result properly', function() {
+ var result = service.handle({config: {data: {listener: {id: 1}}}});
+ expect(result.updated[0].id).toBe(1);
+ });
+
+ });
+})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/row-actions.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/row-actions.service.js
deleted file mode 100644
index bb62eac3..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/row-actions.service.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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.listeners')
- .factory('horizon.dashboard.project.lbaasv2.listeners.actions.rowActions',
- tableRowActions);
-
- tableRowActions.$inject = [
- '$q',
- '$route',
- 'horizon.dashboard.project.lbaasv2.workflow.modal',
- 'horizon.app.core.openstack-service-api.policy',
- 'horizon.framework.util.i18n.gettext',
- 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
- 'horizon.dashboard.project.lbaasv2.listeners.actions.delete',
- 'horizon.dashboard.project.lbaasv2.pools.actions.create'
- ];
-
- /**
- * @ngdoc service
- * @ngname horizon.dashboard.project.lbaasv2.listeners.actions.rowActions
- *
- * @description
- * Provides the service for the Listener 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 gettext The horizon gettext function for translation.
- * @param loadBalancersService The LBaaS v2 load balancers service.
- * @param deleteService The LBaaS v2 listeners delete service.
- * @param createPoolService The LBaaS v2 pools create service.
- * @returns Listeners row actions service object.
- */
-
- function tableRowActions(
- $q, $route, workflowModal, policy, gettext, loadBalancersService, deleteService,
- createPoolService
- ) {
- var loadbalancerId, loadBalancerIsActionable;
-
- var edit = workflowModal.init({
- controller: 'EditListenerWizardController',
- message: gettext('The listener has been updated.'),
- handle: onEdit,
- allowed: canEdit
- });
-
- var service = {
- actions: actions,
- init: init
- };
-
- return service;
-
- ///////////////
-
- function init(_loadbalancerId_) {
- loadbalancerId = _loadbalancerId_;
- loadBalancerIsActionable = loadBalancersService.isActionable(loadbalancerId);
- return service;
- }
-
- function actions() {
- return [{
- service: edit,
- template: {
- text: gettext('Edit')
- }
- },{
- service: createPoolService.init(loadbalancerId, loadBalancerIsActionable).create,
- template: {
- text: gettext('Create Pool')
- }
- },{
- service: deleteService.init(loadbalancerId, loadBalancerIsActionable),
- template: {
- text: gettext('Delete Listener'),
- type: 'delete'
- }
- }];
- }
-
- function canEdit(/*item*/) {
- return $q.all([
- loadBalancerIsActionable,
- policy.ifAllowed({ rules: [['neutron', 'update_listener']] })
- ]);
- }
-
- function onEdit(/*response*/) {
- $route.reload();
- }
- }
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/row-actions.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/row-actions.service.spec.js
deleted file mode 100644
index 15debc82..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/actions/row-actions.service.spec.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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 Listeners Table Row Actions Service', function() {
- var scope, $route, $q, actions, policy, init;
-
- 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_listener']]});
- return allowed;
- }
-
- function isActionableMock(id) {
- if (id === 'active') {
- return $q.when();
- } else {
- return $q.reject();
- }
- }
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- 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('$uibModal', modal);
- }));
-
- beforeEach(inject(function ($injector) {
- scope = $injector.get('$rootScope').$new();
- $q = $injector.get('$q');
- $route = $injector.get('$route');
- policy = $injector.get('horizon.app.core.openstack-service-api.policy');
- var rowActionsService = $injector.get(
- 'horizon.dashboard.project.lbaasv2.listeners.actions.rowActions');
- actions = rowActionsService.actions();
- init = rowActionsService.init;
- var loadbalancerService = $injector.get(
- 'horizon.dashboard.project.lbaasv2.loadbalancers.service');
- spyOn(loadbalancerService, 'isActionable').and.callFake(isActionableMock);
- }));
-
- it('should define correct table row actions', function() {
- expect(actions.length).toBe(3);
- expect(actions[0].template.text).toBe('Edit');
- expect(actions[1].template.text).toBe('Create Pool');
- expect(actions[2].template.text).toBe('Delete Listener');
- });
-
- it('should allow editing a listener of an ACTIVE load balancer', function() {
- init('active');
- expect(canEdit({listenerId: '1234'})).toBe(true);
- });
-
- it('should not allow editing a listener of a non-ACTIVE load balancer', function() {
- init('non-active');
- expect(canEdit({listenerId: '1234'})).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();
- });
-
- });
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/detail.controller.js
deleted file mode 100644
index 3fe9dc33..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/detail.controller.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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.listeners')
- .controller('ListenerDetailController', ListenerDetailController);
-
- ListenerDetailController.$inject = [
- 'horizon.app.core.openstack-service-api.lbaasv2',
- 'horizon.dashboard.project.lbaasv2.listeners.actions.rowActions',
- '$routeParams',
- '$q'
- ];
-
- /**
- * @ngdoc controller
- * @name ListenerDetailController
- *
- * @description
- * Controller for the LBaaS v2 listener detail page.
- *
- * @param api The LBaaS v2 API service.
- * @param rowActions The listener row actions service.
- * @param $routeParams The angular $routeParams service.
- * @param $q The angular service for promises.
- * @returns undefined
- */
-
- function ListenerDetailController(api, rowActions, $routeParams, $q) {
- var ctrl = this;
-
- ctrl.loading = true;
- ctrl.error = false;
- ctrl.actions = rowActions.init($routeParams.loadbalancerId).actions;
-
- init();
-
- ////////////////////////////////
-
- function init() {
- ctrl.listener = null;
- ctrl.loadbalancer = null;
- ctrl.loading = true;
- ctrl.error = false;
- $q.all([
- api.getListener($routeParams.listenerId)
- .then(success('listener'), fail('listener')),
- api.getLoadBalancer($routeParams.loadbalancerId)
- .then(success('loadbalancer'), fail('loadbalancer'))
- ]).then(postInit, initError);
- }
-
- function success(property) {
- return angular.bind(null, function setProp(property, response) {
- ctrl[property] = response.data;
- }, property);
- }
-
- function fail(property) {
- return angular.bind(null, function setProp(property, error) {
- ctrl[property] = null;
- throw error;
- }, property);
- }
-
- function postInit() {
- ctrl.loading = false;
- }
-
- function initError() {
- ctrl.loading = false;
- ctrl.error = true;
- }
-
- }
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/detail.controller.spec.js
deleted file mode 100644
index 586fd2c4..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/detail.controller.spec.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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 Listener Detail Controller', function() {
- var lbaasv2API, $controller, apiFail, qAllFail;
-
- function fakePromise(data, reject) {
- return {
- then: function(success, fail) {
- if (reject) {
- fail();
- } else {
- success({ data: data });
- }
- return fakePromise();
- }
- };
- }
-
- function fakeAPI() {
- return fakePromise('foo', apiFail);
- }
-
- function loadbalancerAPI() {
- return fakePromise({ provisioning_status: 'ACTIVE' });
- }
-
- function qAll() {
- return fakePromise(null, qAllFail);
- }
-
- function createController() {
- return $controller('ListenerDetailController', {
- $routeParams: {
- loadbalancerId: 'loadbalancerId',
- listenerId: 'listenerId'
- }
- });
- }
-
- ///////////////////////
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
- beforeEach(module('horizon.dashboard.project.lbaasv2'));
-
- beforeEach(module(function($provide) {
- apiFail = false;
- qAllFail = false;
-
- $provide.value('$q', { all: qAll });
- $provide.value('$uibModal', {});
- }));
-
- beforeEach(inject(function($injector) {
- lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
- spyOn(lbaasv2API, 'getListener').and.callFake(fakeAPI);
- spyOn(lbaasv2API, 'getLoadBalancer').and.callFake(loadbalancerAPI);
- $controller = $injector.get('$controller');
- }));
-
- it('should invoke lbaasv2 apis', function() {
- var ctrl = createController();
- expect(lbaasv2API.getListener).toHaveBeenCalledWith('listenerId');
- expect(lbaasv2API.getLoadBalancer).toHaveBeenCalledWith('loadbalancerId');
- expect(ctrl.loadbalancer).toEqual({ provisioning_status: 'ACTIVE' });
- expect(ctrl.listener).toBe('foo');
- });
-
- it('should throw error on API fail', function() {
- apiFail = true;
- var init = function() {
- createController();
- };
- expect(init).toThrow();
- });
-
- it('should set error state if any APIs fail', function() {
- qAllFail = true;
- var ctrl = createController();
- expect(ctrl.loading).toBe(false);
- expect(ctrl.error).toBe(true);
- });
-
- });
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/detail.html
deleted file mode 100644
index 3ab4ddbd..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/detail.html
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
-
-
- - Protocol
- - {$ ::ctrl.listener.protocol $}
- - Protocol Port
- - {$ ::ctrl.listener.protocol_port $}
- - Connection Limit
- - {$ ctrl.listener.connection_limit | limit $}
- - Admin State Up
- - {$ ctrl.listener.admin_state_up | yesno $}
- - Default Pool ID
- -
-
- {$ ::ctrl.listener.default_pool_id $}
-
-
- {$ 'None' | translate $}
-
-
- - Listener ID
- - {$ ::ctrl.listener.id $}
- - Project ID
- - {$ ::ctrl.listener.project_id $}
- - Created At
- - {$ ::ctrl.listener.created_at $}
- - Updated At
- - {$ ::ctrl.listener.updated_at $}
-
-
-
-
-
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.controller.js
new file mode 100644
index 00000000..4e450614
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.controller.js
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
+ *
+ * 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.listeners')
+ .controller('ListenerDetailController', ListenerDetailController);
+
+ ListenerDetailController.$inject = [
+ 'loadbalancer',
+ 'listener',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
+ 'horizon.dashboard.project.lbaasv2.listeners.resourceType',
+ 'horizon.framework.conf.resource-type-registry.service',
+ 'horizon.framework.widgets.modal-wait-spinner.service',
+ '$q'
+ ];
+
+ /**
+ * @ngdoc controller
+ * @name ListenerDetailController
+ *
+ * @description
+ * Controller for the LBaaS v2 listener detail page.
+ *
+ * @param loadbalancer The loadbalancer object.
+ * @param listener The listener object.
+ * @param loadBalancersService The LBaaS v2 load balancers service.
+ * @param resourceType The listenr resource type.
+ * @param typeRegistry The horizon resource type registry service.
+ * @param spinnerService The horizon modal wait spinner service.
+ * @param $q The angular service for promises.
+ *
+ * @returns undefined
+ */
+
+ function ListenerDetailController(
+ loadbalancer, listener, loadBalancersService, resourceType, typeRegistry,
+ spinnerService, $q
+ ) {
+ var ctrl = this;
+
+ ctrl.operatingStatus = loadBalancersService.operatingStatus;
+ ctrl.provisioningStatus = loadBalancersService.provisioningStatus;
+ ctrl.loadbalancer = loadbalancer;
+ ctrl.listener = listener;
+ ctrl.listFunctionExtraParams = {
+ loadbalancerId: ctrl.loadbalancer.id,
+ listenerId: ctrl.listener.id
+ };
+ ctrl.resourceType = typeRegistry.getResourceType(resourceType);
+ ctrl.context = {};
+ ctrl.context.identifier = listener.id;
+
+ ctrl.resultHandler = actionResultHandler;
+
+ function actionResultHandler(returnValue) {
+ return $q.when(returnValue, actionSuccessHandler);
+ }
+
+ function loadData(response) {
+ spinnerService.hideModalSpinner();
+ ctrl.showDetails = true;
+ ctrl.resourceType.initActions();
+ ctrl.listener = response.data;
+ ctrl.listener.loadbalancerId = ctrl.loadbalancer.id;
+ }
+
+ function actionSuccessHandler(result) {
+ // The action has completed (for whatever "complete" means to that
+ // action. Notice the view doesn't really need to know the semantics of the
+ // particular action because the actions return data in a standard form.
+ // That return includes the id and type of each created, updated, deleted
+ // and failed item.
+ // Currently just refreshes the display each time.
+ if (result) {
+ spinnerService.showModalSpinner(gettext('Please Wait'));
+ ctrl.showDetails = false;
+ ctrl.context.loadPromise = ctrl.resourceType.load(ctrl.context.identifier);
+ ctrl.context.loadPromise.then(loadData);
+ }
+ }
+
+ }
+
+})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.controller.spec.js
new file mode 100644
index 00000000..b11810bc
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.controller.spec.js
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
+ *
+ * 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 Listener Detail Controller', function() {
+ var deferred, service, ctrl, scope, $timeout, $q, actionResultService;
+
+ ///////////////////////
+
+ beforeEach(module('horizon.dashboard.project.lbaasv2'));
+
+ beforeEach(module(function($provide) {
+ $provide.value('$uibModal', {});
+ }));
+
+ beforeEach(inject(function($controller, $rootScope, _$q_, _$timeout_) {
+ $q = _$q_;
+ deferred = $q.defer();
+ service = {
+ getResourceType: function() {
+ return {
+ load: function() { return deferred.promise; },
+ parsePath: function() { return 'my-context'; },
+ itemName: function() { return 'A name'; },
+ initActions: angular.noop
+ };
+ },
+ getDefaultDetailsTemplateUrl: angular.noop
+ };
+ actionResultService = {
+ getIdsOfType: function() { return []; }
+ };
+ $timeout = _$timeout_;
+ scope = $rootScope.$new();
+ ctrl = $controller('ListenerDetailController', {
+ $scope: scope,
+ loadbalancer: { id: '123' },
+ listener: { 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
+ }
+ });
+ }));
+
+ it('should create a controller', function() {
+ expect(ctrl).toBeDefined();
+ expect(ctrl.loadbalancer).toBeDefined();
+ expect(ctrl.listener).toBeDefined();
+ });
+
+ describe('resultHandler', function() {
+
+ it('handles empty results', function() {
+ var result = $q.defer();
+ result.resolve({});
+ ctrl.resultHandler(result.promise);
+ $timeout.flush();
+ expect(ctrl.showDetails).not.toBe(true);
+ });
+
+ it('handles falsy results', function() {
+ var result = $q.defer();
+ result.resolve(false);
+ ctrl.resultHandler(result.promise);
+ $timeout.flush();
+ expect(ctrl.showDetails).not.toBe(true);
+ });
+
+ it('handles matched results', function() {
+ spyOn(actionResultService, 'getIdsOfType').and.returnValue([1, 2, 3]);
+ var result = $q.defer();
+ result.resolve({some: 'thing'});
+ ctrl.resultHandler(result.promise);
+ deferred.resolve({data: {some: 'data'}});
+ $timeout.flush();
+ expect(ctrl.showDetails).toBe(true);
+ });
+
+ });
+
+ });
+
+})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.html
new file mode 100644
index 00000000..82c3acba
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.html
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/drawer.html b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/drawer.html
new file mode 100644
index 00000000..cec0fec1
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/drawer.html
@@ -0,0 +1,9 @@
+
+
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/listeners.module.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/listeners.module.js
index f97cae75..07515593 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/listeners.module.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/listeners.module.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -26,6 +27,152 @@
*/
angular
- .module('horizon.dashboard.project.lbaasv2.listeners', []);
+ .module('horizon.dashboard.project.lbaasv2.listeners', [])
+ .constant('horizon.dashboard.project.lbaasv2.listeners.resourceType',
+ 'OS::Octavia::Listener')
+ .run(run);
+
+ run.$inject = [
+ 'horizon.framework.conf.resource-type-registry.service',
+ 'horizon.dashboard.project.lbaasv2.basePath',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
+ 'horizon.dashboard.project.lbaasv2.listeners.actions.create',
+ 'horizon.dashboard.project.lbaasv2.listeners.actions.edit',
+ 'horizon.dashboard.project.lbaasv2.listeners.actions.delete',
+ 'horizon.dashboard.project.lbaasv2.listeners.resourceType'
+ ];
+
+ function run(
+ registry,
+ basePath,
+ loadBalancerService,
+ createService,
+ editService,
+ deleteService,
+ resourceType
+ ) {
+ var listenerResourceType = registry.getResourceType(resourceType);
+
+ listenerResourceType
+ .setNames(gettext('Listener'), gettext('Listeners'))
+ .setSummaryTemplateUrl(basePath + 'listeners/details/drawer.html')
+ .setProperties(listenerProperties(loadBalancerService))
+ .setListFunction(loadBalancerService.getListenersPromise)
+ .setLoadFunction(loadBalancerService.getListenerPromise)
+ .tableColumns
+ .append({
+ id: 'name',
+ priority: 1,
+ sortDefault: true,
+ urlFunction: loadBalancerService.getListenerDetailsPath
+ })
+ .append({
+ id: 'protocol',
+ priority: 1
+ })
+ .append({
+ id: 'protocol_port',
+ priority: 1
+ })
+ .append({
+ id: 'operating_status',
+ priority: 1
+ })
+ .append({
+ id: 'provisioning_status',
+ priority: 1
+ })
+ .append({
+ id: 'admin_state_up',
+ priority: 1
+ });
+
+ listenerResourceType.itemActions
+ .append({
+ id: 'listenerEdit',
+ service: editService,
+ template: {
+ text: gettext('Edit Listener')
+ }
+ })
+ .append({
+ id: 'listenerDelete',
+ service: deleteService,
+ template: {
+ text: gettext('Delete Listener'),
+ type: 'delete'
+ }
+ });
+
+ listenerResourceType.globalActions
+ .append({
+ id: 'listenerCreate',
+ service: createService,
+ template: {
+ type: 'create',
+ text: gettext('Create Listener')
+ }
+ });
+
+ listenerResourceType.batchActions
+ .append({
+ id: 'listenerBatchDelete',
+ service: deleteService,
+ template: {
+ text: gettext('Delete Listeners'),
+ type: 'delete-selected'
+ }
+ });
+ }
+
+ function listenerProperties(loadBalancerService) {
+ return {
+ id: gettext('ID'),
+ name: {
+ label: gettext('Name'),
+ filters: ['noName']
+ },
+ description: {
+ label: gettext('Description'),
+ filters: ['noValue']
+ },
+ provisioning_status: {
+ label: gettext('Provisioning Status'),
+ values: loadBalancerService.provisioningStatus
+ },
+ operating_status: {
+ label: gettext('Operating Status'),
+ values: loadBalancerService.operatingStatus
+ },
+ admin_state_up: {
+ label: gettext('Admin State Up'),
+ filters: ['yesno']
+ },
+ protocol: gettext('Protocol'),
+ protocol_port: gettext('Port'),
+ project_id: gettext('Project ID'),
+ created_at: {
+ label: gettext('Created At'),
+ filters: ['noValue']
+ },
+ updated_at: {
+ label: gettext('Updated At'),
+ filters: ['noValue']
+ },
+ connection_limit: {
+ label: gettext('Connection Limit'),
+ filters: ['limit']
+ },
+ default_tls_container_ref: gettext('Default TLS Container Ref'),
+ sni_container_refs: gettext('SNI Container Refs'),
+ default_pool_id: {
+ label: gettext('Default Pool ID'),
+ filters: ['noName']
+ },
+ l7_policies: gettext('L7 Policies'),
+ insert_headers: gettext('Insert Headers'),
+ load_balancers: gettext('Load Balancers')
+ };
+ }
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/listeners.module.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/listeners.module.spec.js
index 9cc8f684..48bb71d9 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/listeners.module.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/listeners.module.spec.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -22,4 +23,46 @@
});
});
+ describe('LBaaS v2 Listeners Registry', function () {
+ var registry, resourceType;
+
+ beforeEach(module('horizon.dashboard.project.lbaasv2'));
+
+ beforeEach(inject(function($injector) {
+ resourceType = $injector.get('horizon.dashboard.project.lbaasv2.listeners.resourceType');
+ registry = $injector.get('horizon.framework.conf.resource-type-registry.service');
+ }));
+
+ it('should define resourceType', function () {
+ expect(resourceType).toBeDefined();
+ });
+
+ it('should register item actions', function () {
+ var actions = registry.getResourceType(resourceType).itemActions;
+ expect(actionHasId(actions, 'listenerEdit')).toBe(true);
+ expect(actionHasId(actions, 'listenerDelete')).toBe(true);
+ });
+
+ it('should register global actions', function () {
+ var actions = registry.getResourceType(resourceType).globalActions;
+ expect(actionHasId(actions, 'listenerCreate')).toBe(true);
+ });
+
+ it('should register batch actions', function () {
+ var actions = registry.getResourceType(resourceType).batchActions;
+ expect(actionHasId(actions, 'listenerBatchDelete')).toBe(true);
+ });
+
+ function actionHasId(list, value) {
+ return list.filter(matchesId).length === 1;
+
+ function matchesId(action) {
+ if (action.id === value) {
+ return true;
+ }
+ }
+ }
+
+ });
+
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/table.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/table.controller.js
deleted file mode 100644
index cfe3b1f4..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/table.controller.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.listeners')
- .controller('ListenersTableController', ListenersTableController);
-
- ListenersTableController.$inject = [
- 'horizon.app.core.openstack-service-api.lbaasv2',
- '$routeParams',
- 'horizon.dashboard.project.lbaasv2.listeners.actions.rowActions',
- 'horizon.dashboard.project.lbaasv2.listeners.actions.batchActions'
- ];
-
- /**
- * @ngdoc controller
- * @name ListenersTableController
- *
- * @description
- * Controller for the LBaaS v2 listeners table. Serves as the focal point for table actions.
- *
- * @param api The LBaaS V2 service API.
- * @param $routeParams The angular $routeParams service.
- * @param rowActions The listener row actions service.
- * @param batchActions The listener batch actions service.
- * @returns undefined
- */
-
- function ListenersTableController(api, $routeParams, rowActions, batchActions) {
-
- var ctrl = this;
- ctrl.items = [];
- ctrl.src = [];
- ctrl.loading = true;
- ctrl.error = false;
- ctrl.checked = {};
- ctrl.loadbalancerId = $routeParams.loadbalancerId;
- ctrl.batchActions = batchActions.init(ctrl.loadbalancerId);
- ctrl.rowActions = rowActions.init(ctrl.loadbalancerId);
-
- init();
-
- ////////////////////////////////
-
- function init() {
- ctrl.src = [];
- ctrl.loading = true;
- ctrl.error = false;
- api.getListeners(ctrl.loadbalancerId).then(success, fail);
- }
-
- function success(response) {
- ctrl.src = response.data.items;
- ctrl.loading = false;
- }
-
- function fail(/*response*/) {
- ctrl.src = [];
- ctrl.loading = false;
- ctrl.error = true;
- }
-
- }
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/table.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/table.controller.spec.js
deleted file mode 100644
index 379f12d2..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/table.controller.spec.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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 Listeners Table Controller', function() {
- var controller, lbaasv2API, rowActions, batchActions;
- var items = [{ foo: 'bar' }];
- var apiFail = false;
-
- function fakeAPI() {
- return {
- then: function(success, fail) {
- if (apiFail && fail) {
- fail();
- } else {
- success({ data: { items: items } });
- }
- }
- };
- }
-
- function initMock() {
- return rowActions;
- }
-
- ///////////////////////
-
- beforeEach(module('horizon.framework.widgets'));
- 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('$uibModal', {});
- }));
-
- beforeEach(inject(function($injector) {
- lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
- controller = $injector.get('$controller');
- rowActions = $injector.get('horizon.dashboard.project.lbaasv2.listeners.actions.rowActions');
- batchActions = $injector.get(
- 'horizon.dashboard.project.lbaasv2.listeners.actions.batchActions');
- spyOn(rowActions, 'init').and.callFake(initMock);
- spyOn(lbaasv2API, 'getListeners').and.callFake(fakeAPI);
- }));
-
- function createController() {
- return controller('ListenersTableController', {
- $routeParams: { loadbalancerId: '1234' }
- });
- }
-
- it('should initialize correctly', function() {
- var ctrl = createController();
- expect(ctrl.items).toEqual([]);
- expect(ctrl.src).toEqual(items);
- expect(ctrl.loading).toBe(false);
- expect(ctrl.error).toBe(false);
- expect(ctrl.checked).toEqual({});
- expect(ctrl.loadbalancerId).toEqual('1234');
- expect(rowActions.init).toHaveBeenCalledWith(ctrl.loadbalancerId);
- expect(ctrl.rowActions).toBeDefined();
- expect(ctrl.rowActions).toEqual(rowActions);
- expect(ctrl.batchActions).toBeDefined();
- expect(ctrl.batchActions).toEqual(batchActions);
- });
-
- it('should invoke lbaasv2 apis', function() {
- var ctrl = createController();
- expect(lbaasv2API.getListeners).toHaveBeenCalled();
- expect(ctrl.src.length).toBe(1);
- });
-
- it('should show error if loading fails', function() {
- apiFail = true;
- var ctrl = createController();
- expect(ctrl.src.length).toBe(0);
- expect(ctrl.error).toBe(true);
- });
-
- });
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/table.html b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/table.html
deleted file mode 100644
index 4376051b..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/table.html
+++ /dev/null
@@ -1,124 +0,0 @@
-
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/associate-ip/modal.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/associate-ip/modal.controller.spec.js
index f0eb5444..622d01a4 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/associate-ip/modal.controller.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/associate-ip/modal.controller.spec.js
@@ -20,7 +20,6 @@
var ctrl, network, floatingIps, floatingIpPools, $controller, $uibModalInstance;
var associateFail = false;
- beforeEach(module('horizon.framework.util.i18n'));
beforeEach(module('horizon.dashboard.project.lbaasv2'));
beforeEach(function() {
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/associate-ip/modal.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/associate-ip/modal.service.js
index cec7389f..a3303cfd 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/associate-ip/modal.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/associate-ip/modal.service.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -18,7 +19,7 @@
angular
.module('horizon.dashboard.project.lbaasv2.loadbalancers')
- .factory('horizon.dashboard.project.lbaasv2.loadbalancers.actions.associate-ip.modal.service',
+ .factory('horizon.dashboard.project.lbaasv2.loadbalancers.actions.associate-ip',
modalService);
modalService.$inject = [
@@ -35,7 +36,7 @@
/**
* @ngdoc service
- * @ngname horizon.dashboard.project.lbaasv2.loadbalancers.actions.associate-ip.modal.service
+ * @ngname horizon.dashboard.project.lbaasv2.loadbalancers.actions.associate-ip
*
* @description
* Provides the service for the Load Balancer Associate Floating IP action.
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/associate-ip/modal.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/associate-ip/modal.service.spec.js
index a70c0334..bd78ba98 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/associate-ip/modal.service.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/associate-ip/modal.service.spec.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -34,10 +35,6 @@
return allowed;
}
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
beforeEach(module('horizon.dashboard.project.lbaasv2'));
beforeEach(function() {
@@ -76,7 +73,7 @@
$route = $injector.get('$route');
$uibModal = $injector.get('$uibModal');
service = $injector.get(
- 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.associate-ip.modal.service');
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.associate-ip');
}));
it('should have the "allowed" and "perform" functions', function() {
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/batch-actions.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/batch-actions.service.spec.js
deleted file mode 100644
index 8095b4b2..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/batch-actions.service.spec.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2015 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 Batch Actions Service', function() {
- var $location, actions, policy;
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- 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('$uibModal', modal);
- }));
-
- beforeEach(inject(function ($injector) {
- $location = $injector.get('$location');
- policy = $injector.get('horizon.app.core.openstack-service-api.policy');
- var batchActionsService = $injector.get(
- 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.batchActions');
- actions = batchActionsService.actions();
- }));
-
- it('should define correct table batch actions', function() {
- expect(actions.length).toBe(2);
- expect(actions[0].template.text).toBe('Create Load Balancer');
- expect(actions[1].template.text).toBe('Delete Load Balancers');
- });
-
- 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 check policy to allow creating a load balancer', function() {
- spyOn(policy, 'ifAllowed').and.returnValue(true);
- var allowed = actions[0].service.allowed();
- expect(allowed).toBe(true);
- expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'create_loadbalancer']]});
- });
-
- it('should redirect after create', function() {
- spyOn($location, 'path').and.callThrough();
- actions[0].service.perform();
- expect($location.path).toHaveBeenCalledWith('project/load_balancer/1');
- });
-
- });
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/batch-actions.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/create/create.service.js
similarity index 54%
rename from octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/batch-actions.service.js
rename to octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/create/create.service.js
index 5684733f..9f52d7ac 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/batch-actions.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/create/create.service.js
@@ -1,5 +1,6 @@
/*
- * Copyright 2015 IBM Corp.
+ * Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -18,76 +19,55 @@
angular
.module('horizon.dashboard.project.lbaasv2.loadbalancers')
- .factory('horizon.dashboard.project.lbaasv2.loadbalancers.actions.batchActions',
- tableBatchActions);
+ .factory('horizon.dashboard.project.lbaasv2.loadbalancers.actions.create', createService);
- tableBatchActions.$inject = [
- '$location',
+ createService.$inject = [
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.resourceType',
+ 'horizon.framework.util.actions.action-result.service',
'horizon.dashboard.project.lbaasv2.workflow.modal',
- 'horizon.dashboard.project.lbaasv2.basePath',
- 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.delete',
'horizon.app.core.openstack-service-api.policy',
'horizon.framework.util.i18n.gettext'
];
/**
* @ngdoc service
- * @ngname horizon.dashboard.project.lbaasv2.loadbalancers.actions.batchActions
+ * @ngname horizon.dashboard.project.lbaasv2.loadbalancers.actions.create
*
* @description
- * Provides the service for the Load Balancers table batch actions.
+ * Provides the service for the create load balancer action.
*
- * @param $location The angular $location service.
+ * @param resourceType The loadbalancer resource type.
+ * @param actionResultService The horizon action result service.
* @param workflowModal The LBaaS workflow modal service.
- * @param basePath The lbaasv2 module base path.
- * @param deleteService The load balancer delete service.
* @param policy The horizon policy service.
* @param gettext The horizon gettext function for translation.
- * @returns Load balancers table batch actions service object.
+ *
+ * @returns Create load balancer action service.
*/
- function tableBatchActions($location, workflowModal, basePath, deleteService, policy, gettext) {
+ function createService(
+ resourceType, actionResultService, workflowModal, policy, gettext
+ ) {
- var create = workflowModal.init({
+ return workflowModal.init({
controller: 'CreateLoadBalancerWizardController',
message: gettext('A new load balancer is being created.'),
- handle: onCreate,
- allowed: canCreate
+ handle: handle,
+ allowed: allowed
});
- var service = {
- actions: actions
- };
-
- return service;
-
- ///////////////
-
- function actions() {
- return [{
- service: create,
- template: {
- type: 'create',
- text: gettext('Create Load Balancer')
- }
- }, {
- service: deleteService,
- template: {
- type: 'delete-selected',
- text: gettext('Delete Load Balancers')
- }
- }];
- }
-
- function canCreate() {
+ function allowed() {
// This rule is made up and should therefore always pass. I assume at some point there
// will be a valid rule similar to this that we will want to use.
return policy.ifAllowed({ rules: [['neutron', 'create_loadbalancer']] });
}
- function onCreate(response) {
- $location.path('project/load_balancer/' + response.data.id);
+ function handle(response) {
+ return actionResultService.getActionResult()
+ .created(resourceType, response.data.id)
+ .result;
}
+
}
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/create/create.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/create/create.service.spec.js
new file mode 100644
index 00000000..d4c9ca08
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/create/create.service.spec.js
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
+ *
+ * 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 Create Load Balancer Action Service', function() {
+ var policy, service;
+
+ beforeEach(module('horizon.dashboard.project.lbaasv2'));
+
+ beforeEach(module(function($provide) {
+ $provide.value('$modal', {
+ open: function() {
+ return {
+ result: {
+ then: function(func) {
+ func({ data: { id: 'loadbalancer1' } });
+ }
+ }
+ };
+ }
+ });
+ }));
+
+ beforeEach(inject(function ($injector) {
+ policy = $injector.get('horizon.app.core.openstack-service-api.policy');
+ service = $injector.get('horizon.dashboard.project.lbaasv2.loadbalancers.actions.create');
+ }));
+
+ it('should check policy to allow creating a load balancer', function() {
+ spyOn(policy, 'ifAllowed').and.returnValue(true);
+ expect(service.allowed()).toBe(true);
+ expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'create_loadbalancer']]});
+ });
+
+ it('should handle the action result properly', function() {
+ var result = service.handle({data: {id: 1}});
+ expect(result.created[0].id).toBe(1);
+ });
+
+ });
+})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/create/wizard.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/create/wizard.controller.spec.js
index c5b94230..e7ff01c1 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/create/wizard.controller.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/create/wizard.controller.spec.js
@@ -29,7 +29,6 @@
};
var scope = {};
- beforeEach(module('horizon.framework.util'));
beforeEach(module('horizon.dashboard.project.lbaasv2'));
beforeEach(module(function ($provide) {
$provide.value('horizon.dashboard.project.lbaasv2.workflow.model', model);
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/delete/delete.action.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/delete/delete.action.service.js
index 26b765ac..9620690c 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/delete/delete.action.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/delete/delete.action.service.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -21,9 +22,9 @@
.factory('horizon.dashboard.project.lbaasv2.loadbalancers.actions.delete', deleteService);
deleteService.$inject = [
- '$q',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.resourceType',
+ 'horizon.framework.util.actions.action-result.service',
'$location',
- '$route',
'horizon.framework.widgets.modal.deleteModalService',
'horizon.app.core.openstack-service-api.lbaasv2',
'horizon.app.core.openstack-service-api.policy',
@@ -36,24 +37,31 @@
* @ngDoc factory
* @name horizon.dashboard.project.lbaasv2.loadbalancers.actions.deleteService
* @description
+ *
* Brings up the delete load balancers confirmation modal dialog.
* On submit, deletes selected load balancers.
* On cancel, does nothing.
- * @param $q The angular service for promises.
+ *
+ * @param resourceType The loadbalancer resource type.
+ * @param actionResultService The horizon action result service.
* @param $location The angular $location service.
- * @param $route The angular $route service.
* @param deleteModal The horizon delete modal service.
* @param api The LBaaS v2 API service.
* @param policy The horizon policy service.
* @param toast The horizon message service.
* @param qExtensions Horizon extensions to the $q service.
* @param gettext The horizon gettext function for translation.
- * @returns The load balancers table delete service.
+ *
+ * @returns The load balancers delete service.
*/
function deleteService(
- $q, $location, $route, deleteModal, api, policy, toast, qExtensions, gettext
+ resourceType, actionResultService, $location, deleteModal, api,
+ policy, toast, qExtensions, gettext
) {
+
+ var scope;
+
// If a batch delete, then this message is displayed for any selected load balancers not in
// ACTIVE or ERROR state.
var notAllowedMessage = gettext('The following load balancers are pending and cannot be ' +
@@ -82,23 +90,34 @@
//////////////
- function perform(items) {
- if (angular.isArray(items)) {
- qExtensions.allSettled(items.map(checkPermission)).then(afterCheck);
- } else {
- deleteModal.open({ $emit: actionComplete }, [items], context);
- }
+ function perform(items, _scope_) {
+ scope = _scope_;
+ var loadbalancers = angular.isArray(items) ? items : [items];
+ return qExtensions.allSettled(loadbalancers.map(checkPermission)).then(afterCheck);
}
- function allowed(item) {
+ function deleteResult(deleteModalResult) {
+ // To make the result of this action generically useful, reformat the return
+ // from the deleteModal into a standard form
+ var actionResult = actionResultService.getActionResult();
+ deleteModalResult.pass.forEach(function markDeleted(item) {
+ actionResult.deleted(resourceType, item.context.id);
+ });
+ deleteModalResult.fail.forEach(function markFailed(item) {
+ actionResult.failed(resourceType, item.context.id);
+ });
+
+ if (actionResult.result.failed.length === 0 && actionResult.result.deleted.length > 0) {
+ var path = 'project/load_balancer';
+ $location.path(path);
+ }
+ return actionResult.result;
+ }
+
+ function allowed() {
// This rule is made up and should therefore always pass. I assume at some point there
// will be a valid rule similar to this that we will want to use.
- var promises = [policy.ifAllowed({ rules: [['neutron', 'delete_loadbalancer']] })];
- if (item) {
- var status = item.provisioning_status;
- promises.push(qExtensions.booleanAsPromise(status === 'ACTIVE' || status === 'ERROR'));
- }
- return $q.all(promises);
+ return policy.ifAllowed({ rules: [['neutron', 'delete_loadbalancer']] });
}
function canBeDeleted(item) {
@@ -115,7 +134,7 @@
toast.add('error', getMessage(notAllowedMessage, result.fail));
}
if (result.pass.length > 0) {
- deleteModal.open({ $emit: actionComplete }, result.pass.map(getEntity), context);
+ return deleteModal.open(scope, result.pass.map(getEntity), context).then(deleteResult);
}
}
@@ -135,20 +154,5 @@
return result.context;
}
- function actionComplete(eventType) {
- if (eventType === context.failedEvent) {
- // Action failed, reload the page
- $route.reload();
- } else {
- // If the user is on the load balancers table then just reload the page, otherwise they
- // are on the details page and we return to the table.
- if (/\/load_balancer(\/)?$/.test($location.path())) {
- $route.reload();
- } else {
- $location.path('project/load_balancer');
- }
- }
- }
-
}
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/delete/delete.action.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/delete/delete.action.service.spec.js
index 86a5c840..76ebb6ca 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/delete/delete.action.service.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/delete/delete.action.service.spec.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -17,17 +18,11 @@
'use strict';
describe('LBaaS v2 Load Balancers Table Row Delete Service', function() {
- var service, policy, modal, lbaasv2Api, $scope, $route, $location, $q, toast, items, path;
+ var service, policy, modal, lbaasv2Api, $scope, $location, $q, toast, items, path;
function allowed(item) {
spyOn(policy, 'ifAllowed').and.returnValue(true);
- var promise = service.allowed(item);
- var allowed;
- promise.then(function() {
- allowed = true;
- }, function() {
- allowed = false;
- });
+ var allowed = service.allowed(item);
$scope.$apply();
expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'delete_loadbalancer']]});
return allowed;
@@ -39,10 +34,6 @@
return def.promise;
}
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
beforeEach(module('horizon.dashboard.project.lbaasv2'));
beforeEach(function() {
@@ -75,7 +66,6 @@
lbaasv2Api = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
modal = $injector.get('horizon.framework.widgets.modal.deleteModalService');
$scope = $injector.get('$rootScope').$new();
- $route = $injector.get('$route');
$location = $injector.get('$location');
$q = $injector.get('$q');
toast = $injector.get('horizon.framework.widgets.toast.service');
@@ -95,24 +85,14 @@
expect(allowed()).toBe(true);
});
- it('should not allow deleting load balancers if state check fails (single)', function() {
- items[0].provisioning_status = 'PENDING_UPDATE';
- expect(allowed(items[0])).toBe(false);
- });
-
- it('should allow batch delete even if state check fails (batch)', function() {
- items[0].provisioning_status = 'PENDING_UPDATE';
- expect(allowed()).toBe(true);
- });
-
it('should open the delete modal', function() {
- spyOn(modal, 'open');
- service.perform(items[0]);
+ spyOn(modal, 'open').and.callThrough();
+ service.perform(items[0], $scope);
$scope.$apply();
expect(modal.open.calls.count()).toBe(1);
var args = modal.open.calls.argsFor(0);
expect(args.length).toBe(3);
- expect(args[0]).toEqual({ $emit: jasmine.any(Function) });
+ expect(args[0]).toEqual($scope);
expect(args[1]).toEqual([jasmine.objectContaining({ id: '1' })]);
expect(args[2]).toEqual(jasmine.objectContaining({
labels: jasmine.any(Object),
@@ -124,7 +104,7 @@
it('should pass function to modal that deletes load balancers', function() {
spyOn(modal, 'open').and.callThrough();
spyOn(lbaasv2Api, 'deleteLoadBalancer').and.callThrough();
- service.perform(items[0]);
+ service.perform(items[0], $scope);
$scope.$apply();
expect(lbaasv2Api.deleteLoadBalancer.calls.count()).toBe(1);
expect(lbaasv2Api.deleteLoadBalancer).toHaveBeenCalledWith('1', true);
@@ -135,7 +115,7 @@
spyOn(toast, 'add');
items[0].provisioning_status = 'PENDING_UPDATE';
items[1].provisioning_status = 'PENDING_DELETE';
- service.perform(items);
+ service.perform(items, $scope);
$scope.$apply();
expect(modal.open).not.toHaveBeenCalled();
expect(toast.add).toHaveBeenCalledWith('error',
@@ -147,7 +127,7 @@
spyOn(lbaasv2Api, 'deleteLoadBalancer').and.returnValue(makePromise(true));
spyOn(toast, 'add');
items.splice(1, 1);
- service.perform(items);
+ service.perform(items, $scope);
$scope.$apply();
expect(modal.open).toHaveBeenCalled();
expect(lbaasv2Api.deleteLoadBalancer.calls.count()).toBe(1);
@@ -155,19 +135,11 @@
'be deleted, possibly due to existing listeners: First.');
});
- it('should reload table after delete', function() {
- path = 'project/load_balancer';
- spyOn($route, 'reload');
- service.perform(items);
- $scope.$apply();
- expect($route.reload).toHaveBeenCalled();
- });
-
- it('should return to table after delete if on detail page', function() {
+ it('should return to panel after delete if on detail page', function() {
path = 'project/load_balancer/1';
spyOn($location, 'path');
spyOn(toast, 'add');
- service.perform(items[0]);
+ service.perform(items[0], $scope);
$scope.$apply();
expect($location.path).toHaveBeenCalledWith('project/load_balancer');
expect(toast.add).toHaveBeenCalledWith('success', 'Deleted load balancers: First.');
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/disassociate-ip/modal.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/disassociate-ip/modal.service.js
index 23370121..4097927d 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/disassociate-ip/modal.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/disassociate-ip/modal.service.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -19,7 +20,7 @@
angular
.module('horizon.dashboard.project.lbaasv2.loadbalancers')
.factory(
- 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.disassociate-ip.modal.service',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.disassociate-ip',
modalService);
modalService.$inject = [
@@ -34,11 +35,13 @@
/**
* @ngDoc factory
- * @name horizon.dashboard.project.lbaasv2.loadbalancers.actions.disassociate-ip.modal.service
+ * @name horizon.dashboard.project.lbaasv2.loadbalancers.actions.disassociate-ip
+ *
* @description
* Brings up the disassociate floating IP confirmation modal dialog.
* On submit, dsiassociates the floating IP address from the load balancer.
* On cancel, does nothing.
+ *
* @param $q The angular service for promises.
* @param $route The angular $route service.
* @param deleteModal The horizon delete modal service.
@@ -46,7 +49,8 @@
* @param policy The horizon policy service.
* @param qExtensions Horizon extensions to the $q service.
* @param gettext The horizon gettext function for translation.
- * @returns The load balancers table row delete service.
+ *
+ * @returns The Disassociate Floating IP modal service.
*/
function modalService($q, $route, deleteModal, network, policy, qExtensions, gettext) {
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/disassociate-ip/modal.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/disassociate-ip/modal.service.spec.js
index 8c07d3b9..45db4936 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/disassociate-ip/modal.service.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/disassociate-ip/modal.service.spec.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -34,10 +35,6 @@
return allowed;
}
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
beforeEach(module('horizon.dashboard.project.lbaasv2'));
beforeEach(function() {
@@ -71,7 +68,7 @@
$scope = $injector.get('$rootScope').$new();
$route = $injector.get('$route');
service = $injector.get(
- 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.disassociate-ip.modal.service');
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.disassociate-ip');
}));
it('should have the "allowed" and "perform" functions', function() {
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/edit/edit.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/edit/edit.service.js
new file mode 100644
index 00000000..f8d6e918
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/edit/edit.service.js
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
+ *
+ * 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.edit', editService);
+
+ editService.$inject = [
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.resourceType',
+ 'horizon.framework.util.actions.action-result.service',
+ '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.edit
+ *
+ * @description
+ * Provides the service for the edit load balancer action.
+ *
+ * @param resourceType The loadbalancer resource type.
+ * @param actionResultService The horizon action result 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 Edit load balancer action service.
+ */
+
+ function editService(
+ resourceType, actionResultService, workflowModal, policy,
+ qExtensions, gettext
+ ) {
+
+ return workflowModal.init({
+ controller: 'EditLoadBalancerWizardController',
+ message: gettext('The load balancer has been updated.'),
+ handle: handle,
+ allowed: allowed
+ });
+
+ ///////////////
+
+ function allowed() {
+ // 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.
+ return policy.ifAllowed({ rules: [['neutron', 'update_loadbalancer']] });
+ }
+
+ function handle(response) {
+ return actionResultService.getActionResult()
+ .updated(resourceType, response.config.data.loadbalancer.id)
+ .result;
+ }
+ }
+
+})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/edit/edit.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/edit/edit.service.spec.js
new file mode 100644
index 00000000..7308e530
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/edit/edit.service.spec.js
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
+ *
+ * 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 Action Service', function() {
+ var service, scope, policy;
+
+ function canEdit(item) {
+ spyOn(policy, 'ifAllowed').and.returnValue(true);
+ var allowed = service.allowed(item);
+ scope.$apply();
+ expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'update_loadbalancer']]});
+ return allowed;
+ }
+
+ beforeEach(module('horizon.dashboard.project.lbaasv2'));
+
+ beforeEach(module(function($provide) {
+ $provide.value('$modal', {
+ open: function() {
+ return {
+ result: {
+ then: function(func) {
+ func();
+ }
+ }
+ };
+ }
+ });
+ }));
+
+ beforeEach(inject(function ($injector) {
+ scope = $injector.get('$rootScope').$new();
+ policy = $injector.get('horizon.app.core.openstack-service-api.policy');
+ service = $injector.get('horizon.dashboard.project.lbaasv2.loadbalancers.actions.edit');
+ }));
+
+ it('should allow editing an load balancer', function() {
+ expect(canEdit({provisioning_status: 'ACTIVE'})).toBe(true);
+ });
+
+ it('should handle the action result properly', function() {
+ var result = service.handle({config: {data: {loadbalancer: {id: 1}}}});
+ expect(result.updated[0].id).toBe(1);
+ });
+
+ });
+})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/edit/wizard.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/edit/wizard.controller.spec.js
index 231dcf4a..46be319a 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/edit/wizard.controller.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/edit/wizard.controller.spec.js
@@ -29,7 +29,6 @@
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);
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/row-actions.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/row-actions.service.js
deleted file mode 100644
index e8b6a8e2..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/row-actions.service.js
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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.dashboard.project.lbaasv2.loadbalancers.actions.delete',
- 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.associate-ip.modal.service',
- 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.disassociate-ip.modal.service',
- 'horizon.app.core.openstack-service-api.policy',
- 'horizon.app.core.openstack-service-api.network',
- '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 deleteService The load balancer delete service.
- * @param associateIp The associate floating IP modal service.
- * @param disassociateIp The disassociate floating IP modal service.
- * @param policy The horizon policy service.
- * @param network The horizon network API service.
- * @param qExtensions Horizon extensions to the $q service.
- * @param gettext The horizon gettext function for translation.
- * @returns Load balancers table row actions service object.
- */
-
- function tableRowActions(
- $q,
- $route,
- workflowModal,
- deleteService,
- associateIp,
- disassociateIp,
- policy,
- network,
- 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')
- }
- },{
- service: associateIp,
- template: {
- text: gettext('Associate Floating IP')
- }
- },{
- service: disassociateIp,
- template: {
- text: gettext('Disassociate Floating IP')
- }
- },{
- service: deleteService,
- template: {
- text: gettext('Delete Load Balancer'),
- type: 'delete'
- }
- }];
- }
-
- 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();
- }
- }
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/row-actions.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/row-actions.service.spec.js
deleted file mode 100644
index 8cb06567..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/row-actions.service.spec.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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'));
- 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('$uibModal', 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(4);
- expect(actions[0].template.text).toBe('Edit');
- expect(actions[1].template.text).toBe('Associate Floating IP');
- expect(actions[2].template.text).toBe('Disassociate Floating IP');
- expect(actions[3].template.text).toBe('Delete Load Balancer');
- });
-
- 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();
- });
-
- });
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/detail.controller.js
deleted file mode 100644
index e01f5f5d..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/detail.controller.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright 2015 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('LoadBalancerDetailController', LoadBalancerDetailController);
-
- LoadBalancerDetailController.$inject = [
- 'horizon.app.core.openstack-service-api.lbaasv2',
- 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.rowActions',
- 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
- '$routeParams',
- '$window',
- '$scope'
- ];
-
- /**
- * @ngdoc controller
- * @name LoadBalancerDetailController
- *
- * @description
- * 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 loadBalancersService The LBaaS v2 load balancers service.
- * @param $routeParams The angular $routeParams service.
- * @param $window Angular's reference to the browser window object.
- * @param $scope The angular scope object.
- * @returns undefined
- */
-
- function LoadBalancerDetailController(
- api, rowActions, loadBalancersService, $routeParams, $window, $scope
- ) {
- var ctrl = this;
-
- ctrl.loading = true;
- ctrl.error = false;
- ctrl.actions = rowActions.actions;
- ctrl.operatingStatus = loadBalancersService.operatingStatus;
- ctrl.provisioningStatus = loadBalancersService.provisioningStatus;
- ctrl.listenersTabActive = $window.listenersTabActive;
-
- init();
-
- ////////////////////////////////
-
- function init() {
- ctrl.loadbalancer = null;
- ctrl.loading = true;
- ctrl.error = false;
- api.getLoadBalancer($routeParams.loadbalancerId, true).then(success, fail);
- }
-
- function success(response) {
- ctrl.loadbalancer = response.data;
- ctrl.loading = false;
- }
-
- function fail(/*response*/) {
- ctrl.loadbalancer = null;
- ctrl.loading = false;
- ctrl.error = true;
- }
-
- // Save the active state of the listeners tab in the global window object so it can stay
- // active after reloading the route following an action.
- $scope.$watch(function() {
- return ctrl.listenersTabActive;
- }, function(active) {
- $window.listenersTabActive = active;
- });
-
- }
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/detail.controller.spec.js
deleted file mode 100644
index 538f0b41..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/detail.controller.spec.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2015 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 Balancer Detail Controller', function() {
- var lbaasv2API, $scope, $window, $controller, apiFail;
-
- function fakeAPI() {
- return {
- then: function(success, fail) {
- if (apiFail && fail) {
- fail();
- } else {
- success({ id: '1234' });
- }
- }
- };
- }
-
- function createController() {
- return $controller('LoadBalancerDetailController', {
- $scope: $scope,
- $window: $window,
- $routeParams: { loadbalancerId: '1234' }
- });
- }
-
- ///////////////////////
-
- beforeEach(module('horizon.framework.widgets'));
- 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) {
- apiFail = false;
- $provide.value('$uibModal', {});
- }));
-
- beforeEach(inject(function($injector) {
- lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
- spyOn(lbaasv2API, 'getLoadBalancer').and.callFake(fakeAPI);
- $scope = $injector.get('$rootScope').$new();
- $window = {};
- $controller = $injector.get('$controller');
- }));
-
- it('should invoke lbaasv2 apis', function() {
- createController();
- expect(lbaasv2API.getLoadBalancer).toHaveBeenCalledWith('1234', true);
- });
-
- it('should save changes to listeners tab active state', function() {
- var ctrl = createController();
- expect($window.listenersTabActive).toBeUndefined();
- expect(ctrl.listenersTabActive).toBeUndefined();
- ctrl.listenersTabActive = true;
- $scope.$apply();
- expect($window.listenersTabActive).toBe(true);
- ctrl.listenersTabActive = false;
- $scope.$apply();
- expect($window.listenersTabActive).toBe(false);
- });
-
- it('should set error state', function() {
- apiFail = true;
- var ctrl = createController();
- expect(ctrl.loading).toBe(false);
- expect(ctrl.error).toBe(true);
- });
-
- });
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/detail.html
deleted file mode 100644
index eccd3f22..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/detail.html
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
-
-
-
-
-
-
-
- - Provider
- - {$ ::ctrl.loadbalancer.provider $}
- - Admin State Up
- - {$ ctrl.loadbalancer.admin_state_up | yesno $}
- - Floating IP Address
- - {$ ctrl.loadbalancer.floating_ip.ip | noValue:('None' | translate) $}
- - Load Balancer ID
- - {$ ::ctrl.loadbalancer.id $}
- - Subnet ID
- -
- {$ ::ctrl.loadbalancer.vip_subnet_id $}
-
- - Port ID
- -
- {$ ::ctrl.loadbalancer.vip_port_id $}
-
- - Created At
- - {$ ::ctrl.loadbalancer.created_at $}
- - Updated At
- - {$ ::ctrl.loadbalancer.updated_at $}
-
-
-
-
-
-
-
-
-
-
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.controller.js
new file mode 100644
index 00000000..3869046e
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.controller.js
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2015 IBM Corp.
+ * Copyright 2017 Walmart.
+ *
+ * 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('LoadBalancerDetailController', LoadBalancerDetailController);
+
+ LoadBalancerDetailController.$inject = [
+ 'loadbalancer',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.resourceType',
+ 'horizon.framework.conf.resource-type-registry.service',
+ 'horizon.framework.widgets.modal-wait-spinner.service',
+ '$q'
+ ];
+
+ /**
+ * @ngdoc controller
+ * @name LoadBalancerDetailController
+ *
+ * @description
+ * Controller for the LBaaS v2 load balancers detail page.
+ *
+ * @param loadbalancer The loadbalancer object.
+ * @param loadBalancersService The LBaaS v2 load balancers service.
+ * @param resourceType The load balancer resource type.
+ * @param typeRegistry The horizon type registry service.
+ * @param spinnerService The horizon modal wait spinner service.
+ * @param $q The angular service for promises.
+ *
+ * @returns undefined
+ */
+
+ function LoadBalancerDetailController(
+ loadbalancer, loadBalancersService, resourceType, typeRegistry,
+ spinnerService, $q
+ ) {
+ var ctrl = this;
+
+ ctrl.operatingStatus = loadBalancersService.operatingStatus;
+ ctrl.provisioningStatus = loadBalancersService.provisioningStatus;
+ ctrl.loadbalancer = loadbalancer;
+ ctrl.listFunctionExtraParams = {
+ loadbalancerId: ctrl.loadbalancer.id
+ };
+ ctrl.resourceType = typeRegistry.getResourceType(resourceType);
+ ctrl.context = {};
+ ctrl.context.identifier = loadbalancer.id;
+
+ ctrl.resultHandler = actionResultHandler;
+
+ function actionResultHandler(returnValue) {
+ return $q.when(returnValue, actionSuccessHandler);
+ }
+
+ function loadData(response) {
+ spinnerService.hideModalSpinner();
+ ctrl.showDetails = true;
+ ctrl.resourceType.initActions();
+ ctrl.loadbalancer = response.data;
+ ctrl.loadbalancer.floating_ip_address = response.data.floating_ip.ip;
+ }
+
+ function actionSuccessHandler(result) {
+ // The action has completed (for whatever "complete" means to that
+ // action. Notice the view doesn't really need to know the semantics of the
+ // particular action because the actions return data in a standard form.
+ // That return includes the id and type of each created, updated, deleted
+ // and failed item.
+ // Currently just refreshes the display each time.
+ if (result) {
+ spinnerService.showModalSpinner(gettext('Please Wait'));
+ ctrl.showDetails = false;
+ ctrl.context.loadPromise = ctrl.resourceType.load(ctrl.context.identifier);
+ ctrl.context.loadPromise.then(loadData);
+ }
+ }
+ }
+
+})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.controller.spec.js
new file mode 100644
index 00000000..9e3e875a
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.controller.spec.js
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2015 IBM Corp.
+ * Copyright 2017 Walmart.
+ *
+ * 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 Balancer Detail Controller', function() {
+ var deferred, service, ctrl, scope, $timeout, $q, actionResultService;
+
+ ///////////////////////
+
+ beforeEach(module('horizon.dashboard.project.lbaasv2'));
+
+ beforeEach(module(function($provide) {
+ $provide.value('$uibModal', {});
+ }));
+
+ beforeEach(inject(function($controller, $rootScope, _$q_, _$timeout_) {
+ $q = _$q_;
+ deferred = $q.defer();
+ service = {
+ getResourceType: function() {
+ return {
+ load: function() { return deferred.promise; },
+ parsePath: function() { return 'my-context'; },
+ itemName: function() { return 'A name'; },
+ initActions: angular.noop
+ };
+ },
+ getDefaultDetailsTemplateUrl: angular.noop
+ };
+ actionResultService = {
+ getIdsOfType: function() { return []; }
+ };
+ $timeout = _$timeout_;
+ scope = $rootScope.$new();
+ ctrl = $controller('LoadBalancerDetailController', {
+ $scope: scope,
+ loadbalancer: { 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
+ }
+ });
+ }));
+
+ it('should create a controller', function() {
+ expect(ctrl).toBeDefined();
+ expect(ctrl.loadbalancer).toBeDefined();
+ });
+
+ describe('resultHandler', function() {
+
+ it('handles empty results', function() {
+ var result = $q.defer();
+ result.resolve({});
+ ctrl.resultHandler(result.promise);
+ $timeout.flush();
+ expect(ctrl.showDetails).not.toBe(true);
+ });
+
+ it('handles falsy results', function() {
+ var result = $q.defer();
+ result.resolve(false);
+ ctrl.resultHandler(result.promise);
+ $timeout.flush();
+ expect(ctrl.showDetails).not.toBe(true);
+ });
+
+ it('handles matched results', function() {
+ spyOn(actionResultService, 'getIdsOfType').and.returnValue([1, 2, 3]);
+ var result = $q.defer();
+ result.resolve({some: 'thing'});
+ ctrl.resultHandler(result.promise);
+ deferred.resolve({data: {some: 'data', floating_ip: {}}});
+ $timeout.flush();
+ expect(ctrl.showDetails).toBe(true);
+ });
+
+ });
+
+ });
+
+})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.html
new file mode 100644
index 00000000..c7bf4449
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.html
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/drawer.html b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/drawer.html
new file mode 100644
index 00000000..c94a628b
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/drawer.html
@@ -0,0 +1,9 @@
+
+
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.module.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.module.js
index ee5fd195..ba1690d8 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.module.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.module.js
@@ -1,5 +1,6 @@
/*
* Copyright 2015 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -26,6 +27,166 @@
*/
angular
- .module('horizon.dashboard.project.lbaasv2.loadbalancers', []);
+ .module('horizon.dashboard.project.lbaasv2.loadbalancers', [])
+ .constant('horizon.dashboard.project.lbaasv2.loadbalancers.resourceType',
+ 'OS::Octavia::LoadBalancer')
+ .run(run);
+
+ run.$inject = [
+ 'horizon.framework.conf.resource-type-registry.service',
+ 'horizon.dashboard.project.lbaasv2.basePath',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.create',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.edit',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.associate-ip',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.disassociate-ip',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.delete',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.resourceType'
+ ];
+
+ function run(
+ registry,
+ basePath,
+ loadBalancerService,
+ createService,
+ editService,
+ associateIpService,
+ disassociateIpService,
+ deleteService,
+ resourceType
+ ) {
+ var loadBalancerResourceType = registry.getResourceType(resourceType);
+
+ loadBalancerResourceType
+ .setNames(gettext('Load Balancer'), gettext('Load Balancers'))
+ .setSummaryTemplateUrl(basePath + 'loadbalancers/details/drawer.html')
+ .setProperties(loadBalancerProperties(loadBalancerService))
+ .setListFunction(loadBalancerService.getLoadBalancersPromise)
+ .setLoadFunction(loadBalancerService.getLoadBalancerPromise)
+ .tableColumns
+ .append({
+ id: 'name',
+ priority: 1,
+ sortDefault: true,
+ urlFunction: loadBalancerService.getDetailsPath
+ })
+ .append({
+ id: 'vip_address',
+ priority: 1
+ })
+ .append({
+ id: 'operating_status',
+ priority: 1
+ })
+ .append({
+ id: 'provisioning_status',
+ priority: 1
+ })
+ .append({
+ id: 'admin_state_up',
+ priority: 1
+ });
+
+ loadBalancerResourceType.itemActions
+ .append({
+ id: 'loadBalancerEdit',
+ service: editService,
+ template: {
+ text: gettext('Edit Load Balancer')
+ }
+ })
+ .append({
+ id: 'loadBalancerAssociateFloatingIp',
+ service: associateIpService,
+ template: {
+ text: gettext('Associate Floating IP')
+ }
+ })
+ .append({
+ id: 'loadBalancerDisassociateFloatingIp',
+ service: disassociateIpService,
+ template: {
+ text: gettext('Disassociate Floating IP')
+ }
+ })
+ .append({
+ id: 'loadBalancerDelete',
+ service: deleteService,
+ template: {
+ text: gettext('Delete Load Balancer'),
+ type: 'delete'
+ }
+ });
+
+ loadBalancerResourceType.globalActions
+ .append({
+ id: 'loadBalancerCreate',
+ service: createService,
+ template: {
+ type: 'create',
+ text: gettext('Create Load Balancer')
+ }
+ });
+
+ loadBalancerResourceType.batchActions
+ .append({
+ id: 'loadBalancerBatchDelete',
+ service: deleteService,
+ template: {
+ text: gettext('Delete Load Balancers'),
+ type: 'delete-selected'
+ }
+ });
+ }
+
+ function loadBalancerProperties(loadBalancerService) {
+ return {
+ id: gettext('ID'),
+ name: {
+ label: gettext('Name'),
+ filters: ['noName']
+ },
+ description: {
+ label: gettext('Description'),
+ filters: ['noValue']
+ },
+ provisioning_status: {
+ label: gettext('Provisioning Status'),
+ values: loadBalancerService.provisioningStatus
+ },
+ operating_status: {
+ label: gettext('Operating Status'),
+ values: loadBalancerService.operatingStatus
+ },
+ admin_state_up: {
+ label: gettext('Admin State Up'),
+ filters: ['yesno']
+ },
+ project_id: gettext('Project ID'),
+ created_at: {
+ label: gettext('Created At'),
+ filters: ['noValue']
+ },
+ updated_at: {
+ label: gettext('Updated At'),
+ filters: ['noValue']
+ },
+ vip_address: gettext('IP Address'),
+ vip_port_id: gettext('Port ID'),
+ vip_subnet_id: gettext('Subnet ID'),
+ vip_network_id: gettext('Network ID'),
+ listeners: gettext('Listeners'),
+ pools: gettext('Pools'),
+ provider: gettext('Provider'),
+ flavor: {
+ label: gettext('Flavor'),
+ filters: ['noValue']
+ },
+ floating_ip_address: {
+ label: gettext('Floating IP'),
+ filters: ['noName']
+ }
+ };
+ }
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.module.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.module.spec.js
index e48dc891..e995caeb 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.module.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.module.spec.js
@@ -1,5 +1,6 @@
/*
* Copyright 2015 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -22,4 +23,48 @@
});
});
+ describe('LBaaS v2 Load Balancers Registry', function () {
+ var registry, resourceType;
+
+ beforeEach(module('horizon.dashboard.project.lbaasv2'));
+
+ beforeEach(inject(function($injector) {
+ resourceType = $injector.get('horizon.dashboard.project.lbaasv2.loadbalancers.resourceType');
+ registry = $injector.get('horizon.framework.conf.resource-type-registry.service');
+ }));
+
+ it('should define resourceType', function () {
+ expect(resourceType).toBeDefined();
+ });
+
+ it('should register item actions', function () {
+ var actions = registry.getResourceType(resourceType).itemActions;
+ expect(actionHasId(actions, 'loadBalancerEdit')).toBe(true);
+ expect(actionHasId(actions, 'loadBalancerAssociateFloatingIp')).toBe(true);
+ expect(actionHasId(actions, 'loadBalancerDisassociateFloatingIp')).toBe(true);
+ expect(actionHasId(actions, 'loadBalancerDelete')).toBe(true);
+ });
+
+ it('should register global actions', function () {
+ var actions = registry.getResourceType(resourceType).globalActions;
+ expect(actionHasId(actions, 'loadBalancerCreate')).toBe(true);
+ });
+
+ it('should register batch actions', function () {
+ var actions = registry.getResourceType(resourceType).batchActions;
+ expect(actionHasId(actions, 'loadBalancerBatchDelete')).toBe(true);
+ });
+
+ function actionHasId(list, value) {
+ return list.filter(matchesId).length === 1;
+
+ function matchesId(action) {
+ if (action.id === value) {
+ return true;
+ }
+ }
+ }
+
+ });
+
})();
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 bcd5be4d..a2ec60d6 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.service.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -29,10 +30,13 @@
/**
* @ngdoc service
* @name horizon.dashboard.project.lbaasv2.loadbalancers.service
+ *
* @description General service for LBaaS v2 load balancers.
+ *
* @param $q The angular service for promises.
* @param api The LBaaS V2 service API.
* @param gettext The horizon gettext function for translation.
+ *
* @returns The load balancers service.
*/
@@ -41,7 +45,8 @@
ONLINE: gettext('Online'),
OFFLINE: gettext('Offline'),
DEGRADED: gettext('Degraded'),
- ERROR: gettext('Error')
+ ERROR: gettext('Error'),
+ NO_MONITOR: gettext('No Monitor')
};
var provisioningStatus = {
@@ -53,9 +58,37 @@
ERROR: gettext('Error')
};
+ var loadBalancerAlgorithm = {
+ ROUND_ROBIN: gettext('Round Robin'),
+ LEAST_CONNECTIONS: gettext('Least Connections'),
+ SOURCE_IP: gettext('Source IP')
+ };
+
+ var none = {
+ null: gettext('None')
+ };
+
var service = {
operatingStatus: operatingStatus,
provisioningStatus: provisioningStatus,
+ loadBalancerAlgorithm: loadBalancerAlgorithm,
+ none: none,
+ nullFilter: nullFilter,
+ getLoadBalancersPromise: getLoadBalancersPromise,
+ getLoadBalancerPromise: getLoadBalancerPromise,
+ getDetailsPath: getDetailsPath,
+ getListenersPromise: getListenersPromise,
+ getListenerPromise: getListenerPromise,
+ getListenerDetailsPath: getListenerDetailsPath,
+ getPoolsPromise: getPoolsPromise,
+ getPoolPromise: getPoolPromise,
+ getPoolDetailsPath: getPoolDetailsPath,
+ getMembersPromise: getMembersPromise,
+ getMemberPromise: getMemberPromise,
+ getMemberDetailsPath: getMemberDetailsPath,
+ getHealthMonitorPromise: getHealthMonitorPromise,
+ getHealthMonitorsPromise: getHealthMonitorsPromise,
+ getHealthMonitorDetailsPath: getHealthMonitorDetailsPath,
isActionable: isActionable
};
@@ -63,6 +96,136 @@
////////////
+ function nullFilter(input) {
+ if (none.hasOwnProperty(input)) {
+ return none[input];
+ }
+ return input;
+ }
+
+ function getMemberDetailsPath(item) {
+ return 'project/load_balancer/' + item.loadbalancerId +
+ '/listeners/' + item.listenerId +
+ '/pools/' + item.poolId +
+ '/members/' + item.id;
+ }
+
+ function getMembersPromise(params) {
+ return api.getMembers(params.poolId).then(modifyResponse);
+
+ function modifyResponse(response) {
+ return {data: {items: response.data.items.map(modifyItem)}};
+
+ function modifyItem(item) {
+ item.trackBy = item.id + item.updated_at;
+ item.loadbalancerId = params.loadbalancerId;
+ item.listenerId = params.listenerId;
+ item.poolId = params.poolId;
+ return item;
+ }
+ }
+ }
+
+ function getMemberPromise(poolId, memberId) {
+ return api.getMember(poolId, memberId);
+ }
+
+ function getHealthMonitorDetailsPath(item) {
+ return 'project/load_balancer/' + item.loadbalancerId +
+ '/listeners/' + item.listenerId +
+ '/pools/' + item.poolId +
+ '/healthmonitors/' + item.id;
+ }
+
+ function getHealthMonitorsPromise(params) {
+ return api.getHealthMonitors(params.poolId).then(modifyResponse);
+
+ function modifyResponse(response) {
+ return {data: {items: response.data.items.map(modifyItem)}};
+
+ function modifyItem(item) {
+ item.trackBy = item.id + item.updated_at;
+ item.loadbalancerId = params.loadbalancerId;
+ item.listenerId = params.listenerId;
+ item.poolId = params.poolId;
+ return item;
+ }
+ }
+ }
+
+ function getHealthMonitorPromise(identifier) {
+ return api.getHealthMonitor(identifier);
+ }
+
+ function getPoolsPromise(params) {
+ return api.getPools(params.loadbalancerId, params.listenerId).then(modifyResponse);
+
+ function modifyResponse(response) {
+ return {data: {items: response.data.items.map(modifyItem)}};
+
+ function modifyItem(item) {
+ item.trackBy = item.id + item.updated_at;
+ item.loadbalancerId = params.loadbalancerId;
+ item.listenerId = params.listenerId;
+ return item;
+ }
+ }
+ }
+
+ function getPoolPromise(identifier) {
+ return api.getPool(identifier);
+ }
+
+ function getPoolDetailsPath(item) {
+ return 'project/load_balancer/' +
+ item.loadbalancerId + '/listeners/' +
+ item.listeners[0].id + '/pools/' + item.id;
+ }
+
+ function getListenersPromise(params) {
+ return api.getListeners(params.loadbalancerId).then(modifyResponse);
+
+ function modifyResponse(response) {
+ return {data: {items: response.data.items.map(modifyItem)}};
+
+ function modifyItem(item) {
+ item.trackBy = item.id + item.updated_at;
+ item.loadbalancerId = params.loadbalancerId;
+ return item;
+ }
+ }
+ }
+
+ function getListenerPromise(identifier) {
+ return api.getListener(identifier);
+ }
+
+ function getListenerDetailsPath(item) {
+ return 'project/load_balancer/' + item.loadbalancerId + '/listeners/' + item.id;
+ }
+
+ function getLoadBalancersPromise() {
+ return api.getLoadBalancers(true).then(modifyResponse);
+
+ function modifyResponse(response) {
+ return {data: {items: response.data.items.map(modifyItem)}};
+
+ function modifyItem(item) {
+ item.trackBy = item.id + item.updated_at;
+ item.floating_ip_address = item.floating_ip.ip;
+ return item;
+ }
+ }
+ }
+
+ function getLoadBalancerPromise(identifier) {
+ return api.getLoadBalancer(identifier, true);
+ }
+
+ function getDetailsPath(item) {
+ return 'project/load_balancer/' + item.id;
+ }
+
/**
* @ngdoc method
* @name horizon.dashboard.project.lbaasv2.loadbalancers.service.isActionable
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 3df0b313..1892d4e9 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
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -17,32 +18,15 @@
'use strict';
describe('LBaaS v2 Load Balancers Service', function() {
- var service, $q, $scope;
+ var service, $q, $scope, api;
- 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('horizon.app.core.openstack-service-api.lbaasv2', {
- getLoadBalancer: function(index) {
- var loadbalancers = [{ provisioning_status: 'ACTIVE' },
- { provisioning_status: 'PENDING_UPDATE' }];
-
- var deferred = $q.defer();
- deferred.resolve({ data: loadbalancers[index] });
-
- return deferred.promise;
- }
- });
- }));
-
beforeEach(inject(function ($injector) {
$q = $injector.get('$q');
$scope = $injector.get('$rootScope').$new();
service = $injector.get('horizon.dashboard.project.lbaasv2.loadbalancers.service');
+ api = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
}));
it('should define value mappings', function() {
@@ -50,16 +34,184 @@
expect(service.provisioningStatus).toBeDefined();
});
- it('should allow checking status of load balancer', function() {
+ it('should filter null property', function() {
+ expect(service.nullFilter('null')).toBe(gettext('None'));
+ expect(service.nullFilter('something else')).toBe('something else');
+ });
+
+ it('getDetailsPath creates urls using the item\'s ID', function() {
+ var myItem = {id: '1234'};
+ expect(service.getDetailsPath(myItem)).toBe('project/load_balancer/1234');
+ });
+
+ it("getLoadBalancersPromise provides a promise", inject(function($timeout) {
+ var deferred = $q.defer();
+ spyOn(api, 'getLoadBalancers').and.returnValue(deferred.promise);
+ var result = service.getLoadBalancersPromise({});
+ deferred.resolve({data: {items: [{id: 1, updated_at: 'feb8', floating_ip: {}}]}});
+ $timeout.flush();
+ expect(result.$$state.value.data.items[0].id).toBe(1);
+ expect(result.$$state.value.data.items[0].updated_at).toBe('feb8');
+ expect(result.$$state.value.data.items[0].trackBy).toBe('1feb8');
+ }));
+
+ it("getLoadBalancerPromise provides a promise", inject(function() {
+ var deferred = $q.defer();
+ spyOn(api, 'getLoadBalancer').and.returnValue(deferred.promise);
+ var result = service.getLoadBalancerPromise({});
+ deferred.resolve({data: {id: 1, updated_at: 'feb8', floating_ip: {}}});
+ expect(result.$$state.value.data.id).toBe(1);
+ expect(result.$$state.value.data.updated_at).toBe('feb8');
+ }));
+
+ it('getListenerDetailsPath creates urls using the item\'s ID', function() {
+ var myItem = {loadbalancerId: '123', id: '456'};
+ expect(service.getListenerDetailsPath(myItem))
+ .toBe('project/load_balancer/123/listeners/456');
+ });
+
+ it("getListenersPromise provides a promise", inject(function($timeout) {
+ var deferred = $q.defer();
+ spyOn(api, 'getListeners').and.returnValue(deferred.promise);
+ var result = service.getListenersPromise({loadbalancerId: 3});
+ deferred.resolve({data: {items: [{id: 1, updated_at: 'feb8'}]}});
+ $timeout.flush();
+ expect(result.$$state.value.data.items[0].id).toBe(1);
+ expect(result.$$state.value.data.items[0].updated_at).toBe('feb8');
+ expect(result.$$state.value.data.items[0].trackBy).toBe('1feb8');
+ expect(result.$$state.value.data.items[0].loadbalancerId).toBe(3);
+ }));
+
+ it("getListenerPromise provides a promise", inject(function() {
+ var deferred = $q.defer();
+ spyOn(api, 'getListener').and.returnValue(deferred.promise);
+ var result = service.getListenerPromise({loadbalancerId: 3});
+ deferred.resolve({data: {id: 1, updated_at: 'feb8', floating_ip: {}}});
+ expect(result.$$state.value.data.id).toBe(1);
+ expect(result.$$state.value.data.updated_at).toBe('feb8');
+ }));
+
+ it('getPoolDetailsPath creates urls using the item\'s ID', function() {
+ var myItem = {loadbalancerId: '123', id: '789', listeners: [{id: '456'}]};
+ expect(service.getPoolDetailsPath(myItem))
+ .toBe('project/load_balancer/123/listeners/456/pools/789');
+ });
+
+ it("getPoolsPromise provides a promise", inject(function($timeout) {
+ var deferred = $q.defer();
+ spyOn(api, 'getPools').and.returnValue(deferred.promise);
+ var result = service.getPoolsPromise({loadbalancerId: 3});
+ deferred.resolve({data: {items: [{id: 1, updated_at: 'feb8'}]}});
+ $timeout.flush();
+ expect(result.$$state.value.data.items[0].id).toBe(1);
+ expect(result.$$state.value.data.items[0].updated_at).toBe('feb8');
+ expect(result.$$state.value.data.items[0].trackBy).toBe('1feb8');
+ expect(result.$$state.value.data.items[0].loadbalancerId).toBe(3);
+ }));
+
+ it("getPoolPromise provides a promise", inject(function() {
+ var deferred = $q.defer();
+ spyOn(api, 'getPool').and.returnValue(deferred.promise);
+ var result = service.getPoolPromise({loadbalancerId: 3});
+ deferred.resolve({data: {id: 1, updated_at: 'feb8'}});
+ expect(result.$$state.value.data.id).toBe(1);
+ expect(result.$$state.value.data.updated_at).toBe('feb8');
+ }));
+
+ it('getMemberDetailsPath creates urls using the item\'s ID', function() {
+ var myItem = {
+ loadbalancerId: '1',
+ listenerId: '2',
+ poolId: '3',
+ id: '4'
+ };
+ expect(service.getMemberDetailsPath(myItem))
+ .toBe('project/load_balancer/1/listeners/2/pools/3/members/4');
+ });
+
+ it("getMembersPromise provides a promise", inject(function($timeout) {
+ var deferred = $q.defer();
+ spyOn(api, 'getMembers').and.returnValue(deferred.promise);
+ var result = service.getMembersPromise({
+ loadbalancerId: 1,
+ listenerId: 2,
+ poolId: 3
+ });
+ deferred.resolve({data: {items: [{id: 4, updated_at: 'feb8'}]}});
+ $timeout.flush();
+ expect(result.$$state.value.data.items[0].id).toBe(4);
+ expect(result.$$state.value.data.items[0].updated_at).toBe('feb8');
+ expect(result.$$state.value.data.items[0].trackBy).toBe('4feb8');
+ expect(result.$$state.value.data.items[0].loadbalancerId).toBe(1);
+ expect(result.$$state.value.data.items[0].listenerId).toBe(2);
+ expect(result.$$state.value.data.items[0].poolId).toBe(3);
+ }));
+
+ it("getMemberPromise provides a promise", inject(function() {
+ var deferred = $q.defer();
+ spyOn(api, 'getMember').and.returnValue(deferred.promise);
+ var result = service.getMemberPromise(2, 1);
+ deferred.resolve({data: {id: 1, updated_at: 'feb8'}});
+ expect(result.$$state.value.data.id).toBe(1);
+ expect(result.$$state.value.data.updated_at).toBe('feb8');
+ }));
+
+ it('getHealthMonitorDetailsPath creates urls using the item\'s ID', function() {
+ var myItem = {
+ loadbalancerId: '1',
+ listenerId: '2',
+ poolId: '3',
+ id: '4'
+ };
+ expect(service.getHealthMonitorDetailsPath(myItem))
+ .toBe('project/load_balancer/1/listeners/2/pools/3/healthmonitors/4');
+ });
+
+ it("getHealthMonitorsPromise provides a promise", inject(function($timeout) {
+ var deferred = $q.defer();
+ spyOn(api, 'getHealthMonitors').and.returnValue(deferred.promise);
+ var result = service.getHealthMonitorsPromise({
+ loadbalancerId: 1,
+ listenerId: 2,
+ poolId: 3
+ });
+ deferred.resolve({data: {items: [{id: 4, updated_at: 'feb8'}]}});
+ $timeout.flush();
+ expect(result.$$state.value.data.items[0].id).toBe(4);
+ expect(result.$$state.value.data.items[0].updated_at).toBe('feb8');
+ expect(result.$$state.value.data.items[0].trackBy).toBe('4feb8');
+ expect(result.$$state.value.data.items[0].loadbalancerId).toBe(1);
+ expect(result.$$state.value.data.items[0].listenerId).toBe(2);
+ expect(result.$$state.value.data.items[0].poolId).toBe(3);
+ }));
+
+ it("getHealthMonitorPromise provides a promise", inject(function() {
+ var deferred = $q.defer();
+ spyOn(api, 'getHealthMonitor').and.returnValue(deferred.promise);
+ var result = service.getHealthMonitorPromise(1);
+ deferred.resolve({data: {id: 1, updated_at: 'feb8'}});
+ expect(result.$$state.value.data.id).toBe(1);
+ expect(result.$$state.value.data.updated_at).toBe('feb8');
+ }));
+
+ it('should allow checking active status of load balancer', function() {
var active = null;
+ var deferred = $q.defer();
+ spyOn(api, 'getLoadBalancer').and.returnValue(deferred.promise);
+ deferred.resolve({data: { provisioning_status: 'ACTIVE'}});
service.isActionable(0).then(function() {
active = true;
});
$scope.$apply();
expect(active).toBe(true);
+ });
- active = null;
- service.isActionable(1).then(angular.noop, function() {
+ it('should allow checking transitional status of load balancer', function() {
+ var active = null;
+ var deferred = $q.defer();
+ spyOn(api, 'getLoadBalancer').and.returnValue(deferred.promise);
+ deferred.resolve({data: { provisioning_status: 'PENDING_UPDATE'}});
+ service.isActionable(0).then(angular.noop, function() {
active = false;
});
$scope.$apply();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/panel.html b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/panel.html
new file mode 100644
index 00000000..d8eb16a6
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/panel.html
@@ -0,0 +1,4 @@
+
+
+
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/table.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/table.controller.js
deleted file mode 100644
index 2046fcff..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/table.controller.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2015 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('LoadBalancersTableController', LoadBalancersTableController);
-
- LoadBalancersTableController.$inject = [
- 'horizon.app.core.openstack-service-api.lbaasv2',
- 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.batchActions',
- 'horizon.dashboard.project.lbaasv2.loadbalancers.actions.rowActions',
- 'horizon.dashboard.project.lbaasv2.loadbalancers.service'
- ];
-
- /**
- * @ngdoc controller
- * @name LoadBalancersTableController
- *
- * @description
- * Controller for the LBaaS v2 load balancers table. Serves as the focal point for table actions.
- *
- * @param api The LBaaS V2 service API.
- * @param batchActions The load balancer batch actions service.
- * @param rowActions The load balancer row actions service.
- * @param loadBalancersService The LBaaS v2 load balancers service.
- * @returns undefined
- */
-
- function LoadBalancersTableController(api, batchActions, rowActions, loadBalancersService) {
-
- var ctrl = this;
- ctrl.items = [];
- ctrl.src = [];
- ctrl.loading = true;
- ctrl.error = false;
- ctrl.checked = {};
- ctrl.batchActions = batchActions;
- ctrl.rowActions = rowActions;
- ctrl.operatingStatus = loadBalancersService.operatingStatus;
- ctrl.provisioningStatus = loadBalancersService.provisioningStatus;
-
- init();
-
- ////////////////////////////////
-
- function init() {
- ctrl.src = [];
- ctrl.loading = true;
- api.getLoadBalancers(true).then(success, fail);
- }
-
- function success(response) {
- ctrl.src = response.data.items;
- ctrl.loading = false;
- }
-
- function fail(/*response*/) {
- ctrl.src = [];
- ctrl.error = true;
- ctrl.loading = false;
- }
-
- }
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/table.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/table.controller.spec.js
deleted file mode 100644
index 933f6c0f..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/table.controller.spec.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2015 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 Controller', function() {
- var controller, lbaasv2API, scope;
- var items = [{ foo: 'bar' }];
- var apiFail = false;
-
- function fakeAPI() {
- return {
- then: function(success, fail) {
- if (apiFail && fail) {
- fail();
- } else {
- success({ data: { items: items } });
- }
- }
- };
- }
-
- ///////////////////////
-
- beforeEach(module('horizon.framework.widgets'));
- 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('$uibModal', {});
- }));
-
- beforeEach(inject(function($injector) {
- lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
- controller = $injector.get('$controller');
- scope = $injector.get('$rootScope').$new();
- spyOn(lbaasv2API, 'getLoadBalancers').and.callFake(fakeAPI);
- }));
-
- function createController() {
- return controller('LoadBalancersTableController', { $scope: scope });
- }
-
- it('should initialize correctly', function() {
- var ctrl = createController();
- expect(ctrl.items).toEqual([]);
- expect(ctrl.src).toEqual(items);
- expect(ctrl.loading).toBe(false);
- expect(ctrl.error).toBe(false);
- expect(ctrl.checked).toEqual({});
- expect(ctrl.batchActions).toBeDefined();
- expect(ctrl.rowActions).toBeDefined();
- expect(ctrl.operatingStatus).toBeDefined();
- expect(ctrl.provisioningStatus).toBeDefined();
- });
-
- it('should invoke lbaasv2 apis', function() {
- var ctrl = createController();
- expect(lbaasv2API.getLoadBalancers).toHaveBeenCalled();
- expect(ctrl.src.length).toBe(1);
- });
-
- it('should show error if loading fails', function() {
- apiFail = true;
- var ctrl = createController();
- expect(ctrl.src.length).toBe(0);
- expect(ctrl.error).toBe(true);
- });
-
- });
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/table.html b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/table.html
deleted file mode 100644
index 03d93e30..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/table.html
+++ /dev/null
@@ -1,155 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- |
-
- |
-
- Name |
- Description |
- Operating Status |
- Provisioning Status |
- IP Address |
- Listeners |
- Actions |
-
-
-
-
-
-
-
-
-
- |
-
-
-
- |
- {$ ::(item.name || item.id) $} |
- {$ ::item.description | noValue $} |
- {$ ::item.operating_status | decode:table.operatingStatus $} |
- {$ ::item.provisioning_status | decode:table.provisioningStatus $} |
- {$ ::item.vip_address $} |
- {$ item.listeners.length $} |
-
-
-
- |
-
-
-
-
-
-
-
-
-
- - IP Address
- - {$ ::item.vip_address $}
-
-
- - Listeners
- - {$ item.listeners.length $}
-
-
-
-
-
-
- - Provider
- - {$ ::item.provider $}
-
-
- - Floating IP Address
- - {$ item.floating_ip.ip || 'None' | translate $}
-
-
- - Admin State Up
- - {$ ::item.admin_state_up | yesno $}
-
-
- - ID
- - {$ ::item.id $}
-
-
- - Subnet ID
- - {$ ::item.vip_subnet_id $}
-
-
- - Port ID
- - {$ ::item.vip_port_id $}
-
-
-
- |
-
-
-
-
-
-
-
-
-
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/batch-actions.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/batch-actions.service.js
deleted file mode 100644
index f8ac9e4c..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/batch-actions.service.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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')
- .factory('horizon.dashboard.project.lbaasv2.members.actions.batchActions',
- tableBatchActions);
-
- tableBatchActions.$inject = [
- 'horizon.framework.util.i18n.gettext',
- 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
- 'horizon.dashboard.project.lbaasv2.members.actions.update-member-list'
- ];
-
- /**
- * @ngdoc service
- * @ngname horizon.dashboard.project.lbaasv2.pools.actions.batchActions
- *
- * @description
- * Provides the service for the Members table batch actions.
- *
- * @param gettext The horizon gettext function for translation.
- * @param loadBalancersService The LBaaS v2 load balancers service.
- * @param updateMemberListService The LBaaS v2 update member list service.
- * @returns Members table batch actions service object.
- */
-
- function tableBatchActions(
- gettext, loadBalancersService, updateMemberListService
- ) {
- var loadBalancerIsActionable, loadBalancerId;
-
- var service = {
- actions: actions,
- init: init
- };
-
- return service;
-
- ///////////////
-
- function init(_loadBalancerId_) {
- loadBalancerId = _loadBalancerId_;
- loadBalancerIsActionable = loadBalancersService.isActionable(loadBalancerId);
- return service;
- }
-
- function actions() {
- return [{
- service: updateMemberListService.init(loadBalancerIsActionable).update,
- template: {
- text: gettext('Add/Remove Pool Members')
- }
- }];
- }
- }
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/batch-actions.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/batch-actions.service.spec.js
deleted file mode 100644
index 110582d0..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/batch-actions.service.spec.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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 Batch Actions Service', function() {
- var actions;
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- 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('$uibModal', modal);
- }));
-
- beforeEach(inject(function ($injector) {
- var batchActionsService = $injector.get(
- 'horizon.dashboard.project.lbaasv2.members.actions.batchActions');
- actions = batchActionsService.actions();
- }));
-
- it('should define correct table batch actions', function() {
- expect(actions.length).toBe(1);
- expect(actions[0].template.text).toBe('Add/Remove Pool Members');
- });
-
- it('should have the "allowed" and "perform" functions', function() {
- actions.forEach(function(action) {
- expect(action.service.allowed).toBeDefined();
- expect(action.service.perform).toBeDefined();
- });
- });
-
- });
-})();
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 fca3e7d2..09ef74cd 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
@@ -21,9 +21,9 @@
.factory('horizon.dashboard.project.lbaasv2.members.actions.delete', deleteService);
deleteService.$inject = [
- '$q',
+ 'horizon.dashboard.project.lbaasv2.members.resourceType',
+ 'horizon.framework.util.actions.action-result.service',
'$location',
- '$route',
'horizon.framework.widgets.modal.deleteModalService',
'horizon.app.core.openstack-service-api.lbaasv2',
'horizon.app.core.openstack-service-api.policy',
@@ -33,22 +33,26 @@
/**
* @ngDoc factory
* @name horizon.dashboard.project.lbaasv2.members.actions.deleteService
+ *
* @description
* Brings up the delete member confirmation modal dialog.
* On submit, deletes selected member.
* On cancel, does nothing.
- * @param $q The angular service for promises.
+ *
+ * @param resourceType The member resource type.
+ * @param actionResultService The horizon action result service.
* @param $location The angular $location service.
- * @param $route The angular $route service.
* @param deleteModal The horizon delete modal service.
* @param api The LBaaS v2 API service.
* @param policy The horizon policy service.
* @param gettext The horizon gettext function for translation.
+ *
* @returns The load balancers table delete service.
*/
- function deleteService($q, $location, $route, deleteModal, api, policy, gettext) {
- var loadbalancerId, listenerId, poolId, statePromise;
+ function deleteService(resourceType, actionResultService,
+ $location, deleteModal, api, policy, gettext) {
+ var loadbalancerId, listenerId, poolId;
var context = {
labels: {
title: gettext('Confirm Delete Member'),
@@ -66,46 +70,51 @@
var service = {
perform: perform,
allowed: allowed,
- init: init
+ deleteResult: deleteResult // exposed just for testing
};
return service;
//////////////
- function init(_loadbalancerId_, _listenerId_, _poolId_, _statePromise_) {
- loadbalancerId = _loadbalancerId_;
- listenerId = _listenerId_;
- poolId = _poolId_;
- statePromise = _statePromise_;
- return service;
- }
-
- function perform(item) {
- deleteModal.open({ $emit: actionComplete }, [item], context);
- }
-
function allowed(/*item*/) {
- return $q.all([
- statePromise,
- // This rule is made up and should therefore always pass. I assume at some point there
- // will be a valid rule similar to this that we will want to use.
- policy.ifAllowed({ rules: [['neutron', 'pool_member_delete']] })
- ]);
+ // This rule is made up and should therefore always pass. I assume at some point there
+ // will be a valid rule similar to this that we will want to use.
+ return policy.ifAllowed({ rules: [['neutron', 'pool_member_delete']] });
+ }
+
+ function perform(items, scope) {
+ var members = angular.isArray(items) ? items : [items];
+ members.map(function(item) {
+ loadbalancerId = item.loadbalancerId;
+ listenerId = item.listenerId;
+ poolId = item.poolId;
+ });
+ return deleteModal.open(scope, members, context).then(deleteResult);
+ }
+
+ function deleteResult(deleteModalResult) {
+ // To make the result of this action generically useful, reformat the return
+ // from the deleteModal into a standard form
+ var actionResult = actionResultService.getActionResult();
+ deleteModalResult.pass.forEach(function markDeleted(item) {
+ actionResult.deleted(resourceType, item.context.id);
+ });
+ deleteModalResult.fail.forEach(function markFailed(item) {
+ actionResult.failed(resourceType, item.context.id);
+ });
+
+ if (actionResult.result.failed.length === 0 && actionResult.result.deleted.length > 0) {
+ var path = 'project/load_balancer/' + loadbalancerId +
+ '/listeners/' + listenerId +
+ '/pools/' + poolId;
+ $location.path(path);
+ }
+ return actionResult.result;
}
function deleteItem(id) {
return api.deleteMember(poolId, id);
}
-
- function actionComplete(eventType) {
- if (eventType === context.successEvent) {
- // Success, go back to pool details page
- var path = 'project/load_balancer/' +
- loadbalancerId + '/listeners/' + listenerId + '/pools/' + poolId;
- $location.path(path);
- }
- $route.reload();
- }
}
})();
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 b3864aa0..2d59fc52 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
@@ -17,138 +17,87 @@
'use strict';
describe('LBaaS v2 Member Delete Service', function() {
- var service, policy, modal, lbaasv2Api, $scope, $location, $q, toast, member;
-
- function allowed(item) {
- spyOn(policy, 'ifAllowed').and.returnValue(makePromise());
- var promise = service.allowed(item);
- var allowed;
- promise.then(function() {
- allowed = true;
- }, function() {
- allowed = false;
- });
- $scope.$apply();
- expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'pool_member_delete']]});
- return allowed;
- }
-
- function makePromise(reject) {
- var def = $q.defer();
- def[reject ? 'reject' : 'resolve']();
- return def.promise;
- }
-
- function isActionable(id) {
- if (id === 'active') {
- return $q.when();
- } else {
- return $q.reject();
- }
- }
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
+ beforeEach(module('horizon.app.core'));
beforeEach(module('horizon.dashboard.project.lbaasv2'));
+ beforeEach(module('horizon.framework'));
- beforeEach(function() {
- member = { id: '1', name: 'Member1' };
- });
+ var deleteModalService, service, lbaasv2API, policyAPI, $location;
- beforeEach(module(function($provide) {
- $provide.value('$uibModal', {
- open: function() {
- return {
- result: makePromise()
- };
- }
- });
- $provide.value('horizon.app.core.openstack-service-api.lbaasv2', {
- deleteMember: function() {
- return makePromise();
- }
- });
- $provide.value('$location', {
- path: function() {
- return '';
- }
- });
- }));
-
- beforeEach(inject(function ($injector) {
- policy = $injector.get('horizon.app.core.openstack-service-api.policy');
- lbaasv2Api = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
- modal = $injector.get('horizon.framework.widgets.modal.deleteModalService');
- $scope = $injector.get('$rootScope').$new();
- $location = $injector.get('$location');
- $q = $injector.get('$q');
- toast = $injector.get('horizon.framework.widgets.toast.service');
+ beforeEach(inject(function($injector) {
service = $injector.get('horizon.dashboard.project.lbaasv2.members.actions.delete');
- service.init('1', '2', '3', isActionable('active'));
- $scope.$apply();
+ lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
+ deleteModalService = $injector.get('horizon.framework.widgets.modal.deleteModalService');
+ policyAPI = $injector.get('horizon.app.core.openstack-service-api.policy');
+ $location = $injector.get('$location');
}));
- it('should have the "allowed" and "perform" functions', function() {
- expect(service.allowed).toBeDefined();
- expect(service.perform).toBeDefined();
+ describe('perform method', function() {
+ beforeEach(function () {
+ // just need for this to return something that looks like a promise but does nothing
+ spyOn(deleteModalService, 'open').and.returnValue({then: angular.noop});
+ });
+
+ it('should open the modal with correct label', function () {
+ service.perform({name: 'spam'});
+ var labels = deleteModalService.open.calls.argsFor(0)[2].labels;
+ expect(deleteModalService.open).toHaveBeenCalled();
+ angular.forEach(labels, function eachLabel(label) {
+ expect(label.toLowerCase()).toContain('member');
+ });
+ });
+
+ it('should open the delete modal with correct entities', function () {
+ service.perform([{name: 'one'}, {name: 'two'}]);
+ var entities = deleteModalService.open.calls.argsFor(0)[1];
+ expect(deleteModalService.open).toHaveBeenCalled();
+ expect(entities.length).toEqual(2);
+ });
+
+ it('should pass in a function that deletes an member', function () {
+ spyOn(lbaasv2API, 'deleteMember').and.callFake(angular.noop);
+ service.perform({poolId: 2, id: 1, name: 'one'});
+ var contextArg = deleteModalService.open.calls.argsFor(0)[2];
+ var deleteFunction = contextArg.deleteEntity;
+ deleteFunction(1);
+ expect(lbaasv2API.deleteMember).toHaveBeenCalledWith(2, 1);
+ });
});
- it('should allow deleting member from load balancer in ACTIVE state', function() {
- expect(allowed()).toBe(true);
- });
-
- it('should not allow deleting member from load balancer in a PENDING state', function() {
- service.init('1', '2', '3', isActionable('pending'));
- expect(allowed()).toBe(false);
- });
-
- it('should open the delete modal', function() {
- spyOn(modal, 'open');
- service.perform(member);
- $scope.$apply();
- expect(modal.open.calls.count()).toBe(1);
- var args = modal.open.calls.argsFor(0);
- expect(args.length).toBe(3);
- expect(args[0]).toEqual({ $emit: jasmine.any(Function) });
- expect(args[1]).toEqual([member]);
- expect(args[2]).toEqual(jasmine.objectContaining({
- labels: jasmine.any(Object),
- deleteEntity: jasmine.any(Function)
- }));
- expect(args[2].labels.title).toBe('Confirm Delete Member');
- });
-
- it('should pass function to modal that deletes the member', function() {
- spyOn(modal, 'open').and.callThrough();
- spyOn(lbaasv2Api, 'deleteMember').and.callThrough();
- service.perform(member);
- $scope.$apply();
- expect(lbaasv2Api.deleteMember.calls.count()).toBe(1);
- expect(lbaasv2Api.deleteMember).toHaveBeenCalledWith('3', '1');
- });
-
- it('should show message if any items fail to be deleted', function() {
- spyOn(modal, 'open').and.callThrough();
- spyOn(lbaasv2Api, 'deleteMember').and.returnValue(makePromise(true));
- spyOn(toast, 'add');
- service.perform(member);
- $scope.$apply();
- expect(modal.open).toHaveBeenCalled();
- expect(lbaasv2Api.deleteMember.calls.count()).toBe(1);
- expect(toast.add).toHaveBeenCalledWith('error', 'The following member could not ' +
- 'be deleted: Member1.');
- });
-
- it('should return to listener details after delete', function() {
+ it('should handle the action result properly', function() {
spyOn($location, 'path');
- spyOn(toast, 'add');
- service.perform(member);
- $scope.$apply();
- expect($location.path).toHaveBeenCalledWith('project/load_balancer/1/listeners/2/pools/3');
- expect(toast.add).toHaveBeenCalledWith('success', 'Deleted member: Member1.');
+ spyOn(deleteModalService, 'open').and.returnValue({then: angular.noop});
+ spyOn(lbaasv2API, 'deleteMember').and.callFake(angular.noop);
+ service.perform({loadbalancerId: 1, listenerId: 2, poolId: 3, id: 1, name: 'one'});
+ var result = service.deleteResult({
+ fail: [],
+ pass: [{
+ context: {
+ id: 1
+ }
+ }]
+ });
+ var path = 'project/load_balancer/1/listeners/2/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');
+ service.allowed();
+ expect(policyAPI.ifAllowed).toHaveBeenCalled();
+ });
+ }); // end of allowed
+
+ }); // end of delete
+
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/edit-member/modal.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/edit-member/modal.service.js
index d26c973b..32cdd4b7 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/edit-member/modal.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/edit-member/modal.service.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -18,13 +19,13 @@
angular
.module('horizon.dashboard.project.lbaasv2.members')
- .factory('horizon.dashboard.project.lbaasv2.members.actions.edit-member.modal.service',
+ .factory('horizon.dashboard.project.lbaasv2.members.actions.edit-member',
modalService);
modalService.$inject = [
- '$q',
+ 'horizon.dashboard.project.lbaasv2.members.resourceType',
+ 'horizon.framework.util.actions.action-result.service',
'$uibModal',
- '$route',
'horizon.dashboard.project.lbaasv2.basePath',
'horizon.app.core.openstack-service-api.policy',
'horizon.framework.widgets.toast.service',
@@ -38,9 +39,9 @@
* @description
* Provides the service for the pool member Edit Member action.
*
- * @param $q The angular service for promises.
+ * @param resourceType The member resource type.
+ * @param actionResultService The horizon action result service.
* @param $uibModal The angular bootstrap $uibModal service.
- * @param $route The angular $route service.
* @param basePath The LBaaS v2 module base path.
* @param policy The horizon policy service.
* @param toastService The horizon toast service.
@@ -50,39 +51,29 @@
*/
function modalService(
- $q,
+ resourceType,
+ actionResultService,
$uibModal,
- $route,
basePath,
policy,
toastService,
gettext
) {
- var poolId, statePromise;
+ var member;
var service = {
perform: open,
- allowed: allowed,
- init: init
+ allowed: allowed
};
return service;
////////////
- function init(_poolId_, _statePromise_) {
- poolId = _poolId_;
- statePromise = _statePromise_;
- return service;
- }
-
function allowed(/*item*/) {
- return $q.all([
- statePromise,
- // 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', 'pool_member_update']] })
- ]);
+ // 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.
+ return policy.ifAllowed({ rules: [['neutron', 'pool_member_update']] });
}
/**
@@ -97,13 +88,14 @@
*/
function open(item) {
+ member = item;
var spec = {
backdrop: 'static',
controller: 'EditMemberModalController as modal',
templateUrl: basePath + 'members/actions/edit-member/modal.html',
resolve: {
poolId: function() {
- return poolId;
+ return item.poolId;
},
member: function() {
return item;
@@ -115,8 +107,9 @@
function onModalClose() {
toastService.add('success', gettext('Pool member has been updated.'));
- $route.reload();
+ return actionResultService.getActionResult()
+ .updated(resourceType, member.id)
+ .result;
}
-
}
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/edit-member/modal.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/edit-member/modal.service.spec.js
index ea91cd97..e2a54a57 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/edit-member/modal.service.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/edit-member/modal.service.spec.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -18,7 +19,7 @@
describe('LBaaS v2 Member Edit Service', function() {
var service, policy, $scope, $route, $uibModal, toast;
- var member = { id: 'member1' };
+ var member = { poolId:'pool1', id: 'member1' };
var fakePromise = function(response) {
return {
@@ -30,14 +31,7 @@
function allowed(item) {
spyOn(policy, 'ifAllowed').and.returnValue(true);
- var promise = service.allowed(item);
- var allowed;
- promise.then(function() {
- allowed = true;
- }, function() {
- allowed = false;
- });
- $scope.$apply();
+ var allowed = service.allowed(item);
expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'pool_member_update']]});
return allowed;
}
@@ -52,7 +46,7 @@
$provide.value('$uibModal', {
open: function() {
return {
- result: fakePromise()
+ result: fakePromise({config: {data: {member: {id: 1}}}})
};
}
});
@@ -65,8 +59,7 @@
$route = $injector.get('$route');
$uibModal = $injector.get('$uibModal');
service = $injector.get(
- 'horizon.dashboard.project.lbaasv2.members.actions.edit-member.modal.service');
- service.init('pool1', fakePromise());
+ 'horizon.dashboard.project.lbaasv2.members.actions.edit-member');
}));
it('should have the "allowed" and "perform" functions', function() {
@@ -96,13 +89,11 @@
expect(resolve.member()).toBe(member);
});
- it('should show message and reload page upon closing modal', function() {
+ it('should show message upon closing modal', function() {
spyOn(toast, 'add');
spyOn($route, 'reload');
service.perform(member);
- $scope.$apply();
expect(toast.add).toHaveBeenCalledWith('success', 'Pool member has been updated.');
- expect($route.reload).toHaveBeenCalled();
});
});
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/row-actions.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/row-actions.service.js
deleted file mode 100644
index 750afa2c..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/row-actions.service.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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')
- .factory('horizon.dashboard.project.lbaasv2.members.actions.rowActions', rowActions);
-
- rowActions.$inject = [
- 'horizon.framework.util.i18n.gettext',
- 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
- 'horizon.dashboard.project.lbaasv2.members.actions.delete',
- 'horizon.dashboard.project.lbaasv2.members.actions.edit-member.modal.service'
- ];
-
- /**
- * @ngdoc service
- * @ngname horizon.dashboard.project.lbaasv2.members.actions.rowActions
- *
- * @description
- * Provides the service for the pool members row actions.
- *
- * @param gettext The horizon gettext function for translation.
- * @param loadBalancersService The LBaaS v2 load balancers service.
- * @param editMember The LBaaS v2 pool member edit service.
- * @returns Members row actions service object.
- */
-
- function rowActions(gettext, loadBalancersService, deleteService, editMember) {
- var loadBalancerIsActionable, loadbalancerId, listenerId, poolId;
-
- var service = {
- actions: actions,
- init: init
- };
-
- return service;
-
- ///////////////
-
- function init(_loadbalancerId_, _listenerId_, _poolId_) {
- loadbalancerId = _loadbalancerId_;
- listenerId = _listenerId_;
- poolId = _poolId_;
- loadBalancerIsActionable = loadBalancersService.isActionable(loadbalancerId);
- return service;
- }
-
- function actions() {
- return [{
- service: editMember.init(poolId, loadBalancerIsActionable),
- template: {
- text: gettext('Edit')
- }
- },{
- service: deleteService.init(loadbalancerId, listenerId, poolId, loadBalancerIsActionable),
- template: {
- text: gettext('Delete Member'),
- type: 'delete'
- }
- }];
- }
- }
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/row-actions.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/row-actions.service.spec.js
deleted file mode 100644
index 6859c4ef..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/row-actions.service.spec.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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 Row Actions Service', function() {
- var actions;
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
- beforeEach(module('horizon.dashboard.project.lbaasv2'));
-
- beforeEach(inject(function ($injector) {
- var rowActionsService = $injector.get(
- 'horizon.dashboard.project.lbaasv2.members.actions.rowActions');
- actions = rowActionsService.init('1', '2', '3').actions();
- var loadbalancerService = $injector.get(
- 'horizon.dashboard.project.lbaasv2.loadbalancers.service');
- spyOn(loadbalancerService, 'isActionable').and.returnValue(true);
- }));
-
- it('should define correct table row actions', function() {
- expect(actions.length).toBe(2);
- expect(actions[0].template.text).toBe('Edit');
- expect(actions[1].template.text).toBe('Delete Member');
- });
-
- it('should have the "allowed" and "perform" functions', function() {
- actions.forEach(function(action) {
- expect(action.service.allowed).toBeDefined();
- expect(action.service.perform).toBeDefined();
- });
- });
-
- });
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/update-list/update-member-list.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/update-list/update-member-list.service.js
index 11692704..5c98fb36 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/update-list/update-member-list.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/update-list/update-member-list.service.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -22,8 +23,8 @@
updateMemberListService);
updateMemberListService.$inject = [
- '$q',
- '$route',
+ 'horizon.dashboard.project.lbaasv2.members.resourceType',
+ 'horizon.framework.util.actions.action-result.service',
'horizon.dashboard.project.lbaasv2.workflow.modal',
'horizon.app.core.openstack-service-api.policy',
'horizon.framework.util.i18n.gettext'
@@ -31,53 +32,38 @@
/**
* @ngDoc factory
- * @name horizon.dashboard.project.lbaasv2.listeners.actions.updateMemberListService
+ * @name horizon.dashboard.project.lbaasv2.members.actions.updateMemberListService
+ *
* @description
* Provides the service for updating the list of pool members.
- * @param $q The angular service for promises.
- * @param $route The angular $route service.
+ *
+ * @param resourceType The member resource type.
+ * @param actionResultService The horizon action result service.
* @param workflowModal The LBaaS workflow modal service.
* @param policy The horizon policy service.
* @param gettext The horizon gettext function for translation.
+ *
* @returns The load balancers members update member list service.
*/
function updateMemberListService(
- $q, $route, workflowModal, policy, gettext
+ resourceType, actionResultService, workflowModal, policy, gettext
) {
- var statePromise;
-
- var updateList = workflowModal.init({
+ return workflowModal.init({
controller: 'UpdateMemberListWizardController',
message: gettext('The pool members have been updated.'),
- handle: onUpdate,
+ handle: handle,
allowed: allowed
});
- var service = {
- init: init,
- update: updateList
- };
-
- return service;
-
- //////////////
-
- function init(_statePromise_) {
- statePromise = _statePromise_;
- return service;
- }
-
function allowed(/*item*/) {
- return $q.all([
- statePromise,
- policy.ifAllowed({ rules: [['neutron', 'update_member_list']] })
- ]);
+ return policy.ifAllowed({ rules: [['neutron', 'update_member_list']] });
}
- function onUpdate(/*response*/) {
- $route.reload();
+ function handle(response) {
+ return actionResultService.getActionResult()
+ .created(resourceType, response.data.id)
+ .result;
}
-
}
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/update-list/update-member-list.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/update-list/update-member-list.service.spec.js
index effe9e91..4d89ed3f 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/update-list/update-member-list.service.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/update-list/update-member-list.service.spec.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -17,85 +18,40 @@
'use strict';
describe('LBaaS v2 Update Member List Action Service', function() {
- var scope, $q, $route, policy, init, updateMemberListService, defer;
+ var policy, service;
- function allowed() {
- spyOn(policy, 'ifAllowed').and.returnValue(true);
- var promise = updateMemberListService.update.allowed();
- var allowed;
- promise.then(function() {
- allowed = true;
- }, function() {
- allowed = false;
- });
- scope.$apply();
- expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'update_member_list']]});
- return allowed;
- }
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
beforeEach(module('horizon.dashboard.project.lbaasv2'));
beforeEach(module(function($provide) {
- var response = {
- data: {
- id: '9012'
- }
- };
- var modal = {
+ $provide.value('$modal', {
open: function() {
return {
result: {
then: function(func) {
- func(response);
+ func({ data: { id: 'listener1' } });
}
}
};
}
- };
- $provide.value('$uibModal', modal);
+ });
}));
beforeEach(inject(function ($injector) {
- scope = $injector.get('$rootScope').$new();
- $q = $injector.get('$q');
policy = $injector.get('horizon.app.core.openstack-service-api.policy');
- $route = $injector.get('$route');
- updateMemberListService = $injector.get(
- 'horizon.dashboard.project.lbaasv2.members.actions.update-member-list');
- init = updateMemberListService.init;
- defer = $q.defer();
+ service = $injector.get(
+ 'horizon.dashboard.project.lbaasv2.members.actions.update-member-list'
+ );
}));
- it('should define the correct service properties', function() {
- expect(updateMemberListService.init).toBeDefined();
- expect(updateMemberListService.update).toBeDefined();
+ it('should check policy to allow updating member list', function() {
+ spyOn(policy, 'ifAllowed').and.returnValue(true);
+ expect(service.allowed()).toBe(true);
+ expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'update_member_list']]});
});
- it('should have the "allowed" and "perform" functions', function() {
- expect(updateMemberListService.update.allowed).toBeDefined();
- expect(updateMemberListService.update.perform).toBeDefined();
- });
-
- it('should allow editing a pool under an ACTIVE load balancer', function() {
- defer.resolve();
- init(defer.promise);
- expect(allowed()).toBe(true);
- });
-
- it('should not allow editing a pool under an NON-ACTIVE load balancer', function() {
- defer.reject();
- init(defer.promise);
- expect(allowed()).toBe(false);
- });
-
- it('should redirect after edit', function() {
- spyOn($route, 'reload').and.callThrough();
- updateMemberListService.update.perform();
- expect($route.reload).toHaveBeenCalled();
+ it('should handle the action result properly', function() {
+ var result = service.handle({data: {id: 1}});
+ expect(result.created[0].id).toBe(1);
});
});
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.js
deleted file mode 100644
index 3cd29a4b..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.js
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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',
- 'horizon.dashboard.project.lbaasv2.members.actions.rowActions',
- '$routeParams',
- '$q',
- 'horizon.dashboard.project.lbaasv2.loadbalancers.service'
- ];
-
- /**
- * @ngdoc controller
- * @name MemberDetailController
- *
- * @description
- * Controller for the LBaaS v2 member detail page.
- *
- * @param api The LBaaS v2 API service.
- * @param rowActions The pool members row actions service.
- * @param $routeParams The angular $routeParams service.
- * @param $q The angular service for promises.
- * @param loadBalancersService The LBaaS v2 load balancers service.
- * @returns undefined
- */
-
- function MemberDetailController(
- api, rowActions, $routeParams, $q, loadBalancersService
- ) {
- var ctrl = this;
-
- ctrl.loading = true;
- ctrl.error = false;
- ctrl.actions = rowActions.init($routeParams.loadbalancerId,
- $routeParams.listenerId, $routeParams.poolId).actions;
- ctrl.loadbalancerId = $routeParams.loadbalancerId;
- ctrl.listenerId = $routeParams.listenerId;
- ctrl.poolId = $routeParams.poolId;
- ctrl.operatingStatus = loadBalancersService.operatingStatus;
- ctrl.provisioningStatus = loadBalancersService.provisioningStatus;
-
- init();
-
- ////////////////////////////////
-
- function init() {
- ctrl.member = null;
- ctrl.pool = null;
- ctrl.listener = null;
- ctrl.loadbalancer = null;
- ctrl.loading = true;
- ctrl.error = false;
- $q.all([
- api.getMember($routeParams.poolId, $routeParams.memberId)
- .then(success('member'), fail('member')),
- api.getPool($routeParams.poolId)
- .then(success('pool'), fail('pool')),
- api.getListener($routeParams.listenerId)
- .then(success('listener'), fail('listener')),
- api.getLoadBalancer($routeParams.loadbalancerId)
- .then(success('loadbalancer'), fail('loadbalancer'))
- ]).then(postInit, initError);
- }
-
- function success(property) {
- return angular.bind(null, function setProp(property, response) {
- ctrl[property] = response.data;
- }, property);
- }
-
- function fail(property) {
- return angular.bind(null, function setProp(property, error) {
- ctrl[property] = null;
- throw error;
- }, property);
- }
-
- function postInit() {
- ctrl.loading = false;
- }
-
- function initError() {
- ctrl.loading = false;
- ctrl.error = true;
- }
-
- }
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.spec.js
deleted file mode 100644
index 9acdbaec..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.spec.js
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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, apiFail, qAllFail, actions;
-
- function fakePromise(data, reject) {
- return {
- then: function(success, fail) {
- if (reject) {
- fail();
- } else {
- success({ data: data });
- }
- return fakePromise();
- }
- };
- }
-
- function fakeAPI() {
- return fakePromise('foo', apiFail);
- }
-
- function loadbalancerAPI() {
- return fakePromise({ provisioning_status: 'ACTIVE' });
- }
-
- function qAll() {
- return fakePromise(null, qAllFail);
- }
-
- function createController() {
- return $controller('MemberDetailController', {
- $routeParams: {
- loadbalancerId: 'loadbalancerId',
- listenerId: 'listenerId',
- poolId: 'poolId',
- memberId: 'memberId'
- }
- });
- }
-
- ///////////////////////
-
- beforeEach(module('horizon.framework.util'));
- 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(module(function($provide) {
- apiFail = false;
- qAllFail = false;
-
- $provide.value('$q', { all: qAll });
- $provide.value('$uibModal', {});
- $provide.value('horizon.dashboard.project.lbaasv2.members.actions.rowActions', {
- init: function() {
- return {
- actions: 'member-actions'
- };
- }
- });
- }));
-
- beforeEach(inject(function($injector) {
- lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
- actions = $injector.get('horizon.dashboard.project.lbaasv2.members.actions.rowActions');
- spyOn(lbaasv2API, 'getMember').and.callFake(fakeAPI);
- spyOn(lbaasv2API, 'getPool').and.callFake(fakeAPI);
- spyOn(lbaasv2API, 'getListener').and.callFake(fakeAPI);
- spyOn(lbaasv2API, 'getLoadBalancer').and.callFake(loadbalancerAPI);
- spyOn(actions, 'init').and.callThrough();
- $controller = $injector.get('$controller');
- }));
-
- it('should invoke lbaasv2 apis', function() {
- var ctrl = createController();
- expect(lbaasv2API.getMember).toHaveBeenCalledWith('poolId','memberId');
- expect(lbaasv2API.getPool).toHaveBeenCalledWith('poolId');
- expect(lbaasv2API.getListener).toHaveBeenCalledWith('listenerId');
- expect(lbaasv2API.getLoadBalancer).toHaveBeenCalledWith('loadbalancerId');
- expect(ctrl.loadbalancerId).toBeDefined();
- expect(ctrl.listenerId).toBeDefined();
- expect(ctrl.poolId).toBeDefined();
- expect(ctrl.operatingStatus).toBeDefined();
- expect(ctrl.provisioningStatus).toBeDefined();
- expect(ctrl.actions).toBe('member-actions');
- expect(actions.init).toHaveBeenCalledWith('loadbalancerId', 'listenerId', 'poolId');
- });
-
- it('should throw error on API fail', function() {
- apiFail = true;
- var init = function() {
- createController();
- };
- expect(init).toThrow();
- });
-
- it('should set error state if any APIs fail', function() {
- qAllFail = true;
- var ctrl = createController();
- expect(ctrl.loading).toBe(false);
- expect(ctrl.error).toBe(true);
- });
-
- });
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.html
deleted file mode 100644
index b450bcd7..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.html
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
-
- - Address
- - {$ ::ctrl.member.address $}
- - Admin State Up
- - {$ ctrl.member.admin_state_up | yesno $}
- - Member ID
- - {$ ::ctrl.member.id $}
- - Operating Status
- - {$ ctrl.member.operating_status | decode:ctrl.operatingStatus $}
- - Project ID
- - {$ ::ctrl.member.project_id $}
- - Protocol Port
- - {$ ::ctrl.member.protocol_port $}
- - Provisioning Status
- - {$ ctrl.member.provisioning_status | decode:ctrl.provisioningStatus $}
- - Subnet ID
- - {$ ctrl.member.subnet_id $}
- - Weight
- - {$ ctrl.member.weight $}
- - Monitor Address
- - {$ ::ctrl.member.monitor_address | noValue:('None' | translate) $}
- - Monitor Port
- - {$ ::ctrl.member.monitor_port | noValue:('None' | translate) $}
- - Created At
- - {$ ::ctrl.member.created_at $}
- - Updated At
- - {$ ::ctrl.member.updated_at $}
-
-
-
-
-
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
new file mode 100644
index 00000000..b6010bd6
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.js
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
+ *
+ * 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 = [
+ 'loadbalancer',
+ 'listener',
+ 'pool',
+ 'member',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
+ 'horizon.dashboard.project.lbaasv2.members.resourceType',
+ 'horizon.framework.conf.resource-type-registry.service',
+ 'horizon.framework.widgets.modal-wait-spinner.service',
+ '$q'
+ ];
+
+ /**
+ * @ngdoc controller
+ * @name MemberDetailController
+ *
+ * @description
+ * Controller for the LBaaS v2 member detail page.
+ *
+ * @param loadbalancer The loadbalancer object.
+ * @param listener The listener object.
+ * @param pool The pool object.
+ * @param member The member object.
+ * @param loadBalancersService The LBaaS v2 load balancers service.
+ * @param resourceType The member resource type.
+ * @param typeRegistry The horizon resource type registry service.
+ * @param spinnerService The horizon modal wait spinner service.
+ * @param $q The angular service for promises.
+ *
+ * @returns undefined
+ */
+
+ function MemberDetailController(
+ loadbalancer, listener, pool, member, loadBalancersService,
+ resourceType, typeRegistry, spinnerService, $q
+ ) {
+ var ctrl = this;
+
+ ctrl.operatingStatus = loadBalancersService.operatingStatus;
+ ctrl.provisioningStatus = loadBalancersService.provisioningStatus;
+ ctrl.loadbalancer = loadbalancer;
+ ctrl.listener = listener;
+ ctrl.pool = pool;
+ ctrl.member = member;
+ ctrl.resourceType = typeRegistry.getResourceType(resourceType);
+ ctrl.context = {};
+ ctrl.context.memberId = member.id;
+ ctrl.context.poolId = pool.id;
+
+ ctrl.resultHandler = actionResultHandler;
+
+ function actionResultHandler(returnValue) {
+ return $q.when(returnValue, actionSuccessHandler);
+ }
+
+ function loadData(response) {
+ spinnerService.hideModalSpinner();
+ ctrl.showDetails = true;
+ ctrl.resourceType.initActions();
+ ctrl.member = response.data;
+ ctrl.member.loadbalancerId = ctrl.loadbalancer.id;
+ ctrl.member.listenerId = ctrl.listener.id;
+ ctrl.member.poolId = ctrl.pool.id;
+ }
+
+ function actionSuccessHandler(result) {
+ // The action has completed (for whatever "complete" means to that
+ // action. Notice the view doesn't really need to know the semantics of the
+ // particular action because the actions return data in a standard form.
+ // That return includes the id and type of each created, updated, deleted
+ // and failed item.
+ // Currently just refreshes the display each time.
+ if (result) {
+ spinnerService.showModalSpinner(gettext('Please Wait'));
+ ctrl.showDetails = false;
+ ctrl.context.loadPromise = ctrl.resourceType.load(
+ ctrl.context.poolId,
+ ctrl.context.memberId
+ );
+ ctrl.context.loadPromise.then(loadData);
+ }
+ }
+ }
+
+})();
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
new file mode 100644
index 00000000..bc7aca0a
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.spec.js
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
+ *
+ * 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 deferred, service, ctrl, scope, $timeout, $q, actionResultService;
+
+ ///////////////////////
+
+ beforeEach(module('horizon.dashboard.project.lbaasv2'));
+
+ beforeEach(module(function($provide) {
+ $provide.value('$uibModal', {});
+ }));
+
+ beforeEach(inject(function($controller, $rootScope, _$q_, _$timeout_) {
+ $q = _$q_;
+ deferred = $q.defer();
+ service = {
+ getResourceType: function() {
+ return {
+ load: function() { return deferred.promise; },
+ parsePath: function() { return 'my-context'; },
+ itemName: function() { return 'A name'; },
+ initActions: angular.noop
+ };
+ },
+ getDefaultDetailsTemplateUrl: angular.noop
+ };
+ actionResultService = {
+ getIdsOfType: function() { return []; }
+ };
+ $timeout = _$timeout_;
+ scope = $rootScope.$new();
+ ctrl = $controller('MemberDetailController', {
+ $scope: scope,
+ loadbalancer: { id: '123' },
+ listener: { id: '123' },
+ 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
+ }
+ });
+ }));
+
+ it('should create a controller', function() {
+ expect(ctrl).toBeDefined();
+ expect(ctrl.loadbalancer).toBeDefined();
+ expect(ctrl.listener).toBeDefined();
+ expect(ctrl.pool).toBeDefined();
+ expect(ctrl.member).toBeDefined();
+ });
+
+ describe('resultHandler', function() {
+
+ it('handles empty results', function() {
+ var result = $q.defer();
+ result.resolve({});
+ ctrl.resultHandler(result.promise);
+ $timeout.flush();
+ expect(ctrl.showDetails).not.toBe(true);
+ });
+
+ it('handles falsy results', function() {
+ var result = $q.defer();
+ result.resolve(false);
+ ctrl.resultHandler(result.promise);
+ $timeout.flush();
+ expect(ctrl.showDetails).not.toBe(true);
+ });
+
+ it('handles matched results', function() {
+ spyOn(actionResultService, 'getIdsOfType').and.returnValue([1, 2, 3]);
+ var result = $q.defer();
+ result.resolve({some: 'thing'});
+ ctrl.resultHandler(result.promise);
+ deferred.resolve({data: {some: 'data'}});
+ $timeout.flush();
+ expect(ctrl.showDetails).toBe(true);
+ });
+
+ });
+
+ });
+
+})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.html
new file mode 100644
index 00000000..d21b4ada
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.html
@@ -0,0 +1,55 @@
+
+
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/drawer.html b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/drawer.html
new file mode 100644
index 00000000..05d61a7b
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/drawer.html
@@ -0,0 +1,9 @@
+
+
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/members.module.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/members.module.js
index 0beeab5e..c1ad2606 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/members.module.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/members.module.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -26,6 +27,149 @@
*/
angular
- .module('horizon.dashboard.project.lbaasv2.members', []);
+ .module('horizon.dashboard.project.lbaasv2.members', [])
+ .constant('horizon.dashboard.project.lbaasv2.members.resourceType',
+ 'OS::Octavia::Member')
+ .run(run);
+
+ run.$inject = [
+ 'horizon.framework.conf.resource-type-registry.service',
+ 'horizon.dashboard.project.lbaasv2.basePath',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
+ 'horizon.dashboard.project.lbaasv2.members.actions.update-member-list',
+ 'horizon.dashboard.project.lbaasv2.members.actions.edit-member',
+ 'horizon.dashboard.project.lbaasv2.members.actions.delete',
+ 'horizon.dashboard.project.lbaasv2.members.resourceType'
+ ];
+
+ function run(
+ registry,
+ basePath,
+ loadBalancerService,
+ createService,
+ editService,
+ deleteService,
+ resourceType
+ ) {
+ var memberResourceType = registry.getResourceType(resourceType);
+
+ memberResourceType
+ .setNames(gettext('Member'), gettext('Members'))
+ .setSummaryTemplateUrl(basePath + 'members/details/drawer.html')
+ .setProperties(memberProperties(loadBalancerService))
+ .setListFunction(loadBalancerService.getMembersPromise)
+ .setLoadFunction(loadBalancerService.getMemberPromise)
+ .tableColumns
+ .append({
+ id: 'name',
+ priority: 1,
+ sortDefault: true,
+ urlFunction: loadBalancerService.getMemberDetailsPath
+ })
+ .append({
+ id: 'address',
+ priority: 1
+ })
+ .append({
+ id: 'protocol_port',
+ priority: 1
+ })
+ .append({
+ id: 'weight',
+ priority: 1
+ })
+ .append({
+ id: 'operating_status',
+ priority: 1
+ })
+ .append({
+ id: 'provisioning_status',
+ priority: 1
+ })
+ .append({
+ id: 'admin_state_up',
+ priority: 1
+ });
+
+ memberResourceType.itemActions
+ .append({
+ id: 'memberEdit',
+ service: editService,
+ template: {
+ text: gettext('Edit Member')
+ }
+ })
+ .append({
+ id: 'memberDelete',
+ service: deleteService,
+ template: {
+ text: gettext('Delete Member'),
+ type: 'delete'
+ }
+ });
+
+ memberResourceType.globalActions
+ .append({
+ id: 'memberCreate',
+ service: createService,
+ template: {
+ type: 'create',
+ text: gettext('Add/Remove Members')
+ }
+ });
+
+ memberResourceType.batchActions
+ .append({
+ id: 'memberBatchDelete',
+ service: deleteService,
+ template: {
+ text: gettext('Delete Members'),
+ type: 'delete-selected'
+ }
+ });
+ }
+
+ function memberProperties(loadBalancerService) {
+ return {
+ id: gettext('ID'),
+ name: {
+ label: gettext('Name'),
+ filters: ['noName']
+ },
+ provisioning_status: {
+ label: gettext('Provisioning Status'),
+ values: loadBalancerService.provisioningStatus
+ },
+ operating_status: {
+ label: gettext('Operating Status'),
+ values: loadBalancerService.operatingStatus
+ },
+ admin_state_up: {
+ label: gettext('Admin State Up'),
+ filters: ['yesno']
+ },
+ address: gettext('IP Address'),
+ protocol_port: gettext('Port'),
+ weight: gettext('Weight'),
+ subnet_id: gettext('Subnet ID'),
+ project_id: gettext('Project ID'),
+ created_at: {
+ label: gettext('Created At'),
+ filters: ['noValue']
+ },
+ updated_at: {
+ label: gettext('Updated At'),
+ filters: ['noValue']
+ },
+ monitor_address: {
+ label: gettext('Monitor Address'),
+ filters: ['noName']
+ },
+ monitor_port: {
+ label: gettext('Monitor Port'),
+ filters: ['noName']
+ }
+ };
+ }
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/members.module.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/members.module.spec.js
index 1806d831..e88b0644 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/members.module.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/members.module.spec.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -22,4 +23,46 @@
});
});
+ describe('LBaaS v2 Members Registry', function () {
+ var registry, resourceType;
+
+ beforeEach(module('horizon.dashboard.project.lbaasv2'));
+
+ beforeEach(inject(function($injector) {
+ resourceType = $injector.get('horizon.dashboard.project.lbaasv2.members.resourceType');
+ registry = $injector.get('horizon.framework.conf.resource-type-registry.service');
+ }));
+
+ it('should define resourceType', function () {
+ expect(resourceType).toBeDefined();
+ });
+
+ it('should register item actions', function () {
+ var actions = registry.getResourceType(resourceType).itemActions;
+ expect(actionHasId(actions, 'memberEdit')).toBe(true);
+ expect(actionHasId(actions, 'memberDelete')).toBe(true);
+ });
+
+ it('should register global actions', function () {
+ var actions = registry.getResourceType(resourceType).globalActions;
+ expect(actionHasId(actions, 'memberCreate')).toBe(true);
+ });
+
+ it('should register batch actions', function () {
+ var actions = registry.getResourceType(resourceType).batchActions;
+ expect(actionHasId(actions, 'memberBatchDelete')).toBe(true);
+ });
+
+ function actionHasId(list, value) {
+ return list.filter(matchesId).length === 1;
+
+ function matchesId(action) {
+ if (action.id === value) {
+ return true;
+ }
+ }
+ }
+
+ });
+
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.controller.js
deleted file mode 100644
index 7f3a6160..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.controller.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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',
- 'horizon.dashboard.project.lbaasv2.members.actions.rowActions',
- 'horizon.dashboard.project.lbaasv2.members.actions.batchActions',
- '$routeParams',
- 'horizon.dashboard.project.lbaasv2.loadbalancers.service'
- ];
-
- /**
- * @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 rowActions The pool members row actions service.
- * @param batchActions The members batch actions service.
- * @param $routeParams The angular $routeParams service.
- * @param loadBalancersService The LBaaS v2 load balancers service.
- * @returns undefined
- */
-
- function MembersTableController(
- api, rowActions, batchActions, $routeParams, loadBalancersService
- ) {
- var ctrl = this;
- ctrl.items = [];
- ctrl.src = [];
- ctrl.loading = true;
- ctrl.error = false;
- ctrl.checked = {};
- ctrl.loadbalancerId = $routeParams.loadbalancerId;
- ctrl.listenerId = $routeParams.listenerId;
- ctrl.poolId = $routeParams.poolId;
- ctrl.rowActions = rowActions.init(ctrl.loadbalancerId, ctrl.listenerId, ctrl.poolId);
- ctrl.batchActions = batchActions.init(ctrl.loadbalancerId);
- ctrl.operatingStatus = loadBalancersService.operatingStatus;
- ctrl.provisioningStatus = loadBalancersService.provisioningStatus;
-
- init();
-
- ////////////////////////////////
-
- function init() {
- ctrl.src = [];
- ctrl.loading = true;
- ctrl.error = false;
- api.getMembers(ctrl.poolId).then(success, fail);
- }
-
- function success(response) {
- ctrl.src = response.data.items;
- ctrl.loading = false;
- }
-
- function fail(/*response*/) {
- ctrl.src = [];
- ctrl.loading = false;
- ctrl.error = true;
- }
-
- }
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.controller.spec.js
deleted file mode 100644
index 37b59999..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.controller.spec.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2016 IBM Corp.
- * Copyright 2017 Walmart.
- *
- * 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, actions;
- var items = [{ foo: 'bar' }];
- var apiFail = false;
-
- function fakeAPI() {
- return {
- then: function(success, fail) {
- if (apiFail && fail) {
- fail();
- } else {
- success({ data: { 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('$uibModal', {});
- $provide.value('horizon.dashboard.project.lbaasv2.members.actions.rowActions', {
- init: function() {
- return {
- actions: 'member-actions'
- };
- }
- });
- }));
-
- beforeEach(inject(function($injector) {
- lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
- actions = $injector.get('horizon.dashboard.project.lbaasv2.members.actions.rowActions');
- controller = $injector.get('$controller');
- spyOn(lbaasv2API, 'getMembers').and.callFake(fakeAPI);
- spyOn(actions, 'init').and.callThrough();
- }));
-
- function createController() {
- return controller('MembersTableController', {
- $scope: scope,
- $routeParams: {
- loadbalancerId: 'loadbalancerId',
- listenerId: 'listenerId',
- poolId: 'poolId'
- }});
- }
-
- it('should initialize the controller properties correctly', function() {
- var ctrl = createController();
- expect(ctrl.items).toEqual([]);
- expect(ctrl.src).toEqual(items);
- expect(ctrl.loading).toBe(false);
- expect(ctrl.error).toBe(false);
- expect(ctrl.checked).toEqual({});
- expect(ctrl.loadbalancerId).toBeDefined();
- expect(ctrl.listenerId).toBeDefined();
- expect(ctrl.poolId).toBeDefined();
- expect(ctrl.rowActions).toBeDefined();
- expect(ctrl.batchActions).toBeDefined();
- expect(ctrl.operatingStatus).toBeDefined();
- expect(ctrl.provisioningStatus).toBeDefined();
- });
-
- it('should invoke lbaasv2 apis', function() {
- var ctrl = createController();
- expect(lbaasv2API.getMembers).toHaveBeenCalled();
- expect(ctrl.src.length).toBe(1);
- });
-
- it('should show error if loading fails', function() {
- apiFail = true;
- var ctrl = createController();
- expect(ctrl.src.length).toBe(0);
- expect(ctrl.error).toBe(true);
- });
-
- });
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.html b/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.html
deleted file mode 100644
index a948613b..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.html
+++ /dev/null
@@ -1,120 +0,0 @@
-
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 4174c461..ba1b5eb9 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
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -21,69 +22,59 @@
.factory('horizon.dashboard.project.lbaasv2.pools.actions.create', createService);
createService.$inject = [
+ 'horizon.dashboard.project.lbaasv2.pools.resourceType',
+ 'horizon.framework.util.actions.action-result.service',
'$q',
- '$location',
'horizon.dashboard.project.lbaasv2.workflow.modal',
'horizon.app.core.openstack-service-api.policy',
+ 'horizon.framework.util.i18n.gettext',
'horizon.framework.util.q.extensions',
- 'horizon.framework.util.i18n.gettext'
+ '$routeParams'
];
/**
* @ngDoc factory
- * @name horizon.dashboard.project.lbaasv2.listeners.actions.createService
+ * @name horizon.dashboard.project.lbaasv2.pools.actions.createService
+ *
* @description
* Provides the service for creating a pool resource.
+ *
+ * @param resourceType The pool resource type.
+ * @param actionResultService The horizon action result service.
* @param $q The angular service for promises.
- * @param $location The angular $location 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 The load balancers pool create service.
+ * @param qExtensions horizon extensions to the $q service.
+ * @param $routeParams The angular $routeParams service.
+ *
+ * @returns The pool create service.
*/
function createService(
- $q, $location, workflowModal, policy, qExtensions, gettext
+ resourceType, actionResultService,
+ $q, workflowModal, policy, gettext, qExtensions, $routeParams
) {
- var loadbalancerId, listenerId, statePromise;
-
- var create = workflowModal.init({
+ return workflowModal.init({
controller: 'CreatePoolWizardController',
message: gettext('A new pool is being created.'),
- handle: onCreate,
+ handle: handle,
allowed: allowed
});
- var service = {
- init: init,
- create: create
- };
-
- return service;
-
//////////////
- function init(_loadbalancerId_, _statePromise_) {
- loadbalancerId = _loadbalancerId_;
- statePromise = _statePromise_;
- return service;
- }
-
- function allowed(item) {
- listenerId = item.id;
+ function allowed() {
return $q.all([
- statePromise,
- qExtensions.booleanAsPromise(!item.default_pool_id),
+ qExtensions.booleanAsPromise(!!$routeParams.listenerId),
policy.ifAllowed({ rules: [['neutron', 'create_pool']] })
]);
}
- function onCreate(response) {
- var poolId = response.data.id;
- $location.path('project/load_balancer/' + loadbalancerId + '/listeners/' +
- listenerId + '/pools/' + poolId);
+ function handle(response) {
+ return actionResultService.getActionResult()
+ .created(resourceType, response.data.id)
+ .result;
}
-
}
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/create/create.action.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/create/create.action.service.spec.js
index d05c7dd2..ad511e1d 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/create/create.action.service.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/create/create.action.service.spec.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -17,95 +18,49 @@
'use strict';
describe('LBaaS v2 Create Pool Action Service', function() {
- var scope, $q, $location, policy, init, createPoolService, defer;
+ var policy, service;
- function allowed(item) {
- spyOn(policy, 'ifAllowed').and.returnValue(true);
- var promise = createPoolService.create.allowed(item);
- var allowed;
- promise.then(function() {
- allowed = true;
- }, function() {
- allowed = false;
- });
- scope.$apply();
- expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'create_pool']]});
- return allowed;
- }
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
beforeEach(module('horizon.dashboard.project.lbaasv2'));
beforeEach(module(function($provide) {
- var response = {
- data: {
- id: '9012'
- }
- };
- var modal = {
+ $provide.value('$modal', {
open: function() {
return {
result: {
then: function(func) {
- func(response);
+ func({ data: { id: 'listener1' } });
}
}
};
}
- };
- $provide.value('$uibModal', modal);
+ });
+ $provide.value('$routeParams', {});
}));
beforeEach(inject(function ($injector) {
- scope = $injector.get('$rootScope').$new();
- $q = $injector.get('$q');
policy = $injector.get('horizon.app.core.openstack-service-api.policy');
- $location = $injector.get('$location');
- createPoolService = $injector.get(
- 'horizon.dashboard.project.lbaasv2.pools.actions.create');
- init = createPoolService.init;
- defer = $q.defer();
+ service = $injector.get('horizon.dashboard.project.lbaasv2.pools.actions.create');
}));
- it('should define the correct service properties', function() {
- expect(createPoolService.init).toBeDefined();
- expect(createPoolService.create).toBeDefined();
+ it('should not allow creating a pool if listenerId is not present', function() {
+ spyOn(policy, 'ifAllowed').and.returnValue(true);
+ var allowed = service.allowed();
+ permissionShouldFail(allowed);
});
- it('should have the "allowed" and "perform" functions', function() {
- expect(createPoolService.create.allowed).toBeDefined();
- expect(createPoolService.create.perform).toBeDefined();
- });
-
- it('should allow creating a pool under an ACTIVE load balancer', function() {
- defer.resolve();
- init('active', defer.promise);
- expect(allowed({default_pool_id: ''})).toBe(true);
- });
-
- it('should not allow creating a pool under an NON-ACTIVE load balancer', function() {
- defer.reject();
- init('non-active', defer.promise);
- expect(allowed({default_pool_id: ''})).toBe(false);
- });
-
- it('should not allow creating a pool if a listener pool already exists', function() {
- defer.resolve();
- init('active', defer.promise);
- expect(allowed({default_pool_id: '1234'})).toBe(false);
- });
-
- it('should redirect after create', function() {
- defer.resolve();
- spyOn($location, 'path').and.callThrough();
- init('1234', defer.promise).create.allowed({id: '5678'});
- createPoolService.create.perform();
- expect($location.path).toHaveBeenCalledWith(
- 'project/load_balancer/1234/listeners/5678/pools/9012');
+ it('should handle the action result properly', function() {
+ var result = service.handle({data: {id: 1}});
+ expect(result.created[0].id).toBe(1);
});
+ function permissionShouldFail(permissions) {
+ permissions.then(
+ function() {
+ expect(false).toBe(true);
+ },
+ function() {
+ expect(true).toBe(true);
+ });
+ }
});
})();
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 e1cccda0..9d0006cf 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
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -30,6 +31,7 @@
function CreatePoolWizardController($scope, $routeParams, model, workflowService, gettext) {
var loadbalancerId = $routeParams.loadbalancerId;
+ var listenerId = $routeParams.listenerId;
var scope = $scope;
scope.model = model;
scope.submit = scope.model.submit;
@@ -38,7 +40,7 @@
'fa fa-cloud-download',
['pool', 'members', 'monitor']
);
- scope.model.initialize('pool', false, loadbalancerId, scope.launchContext.id);
+ scope.model.initialize('pool', false, loadbalancerId, listenerId);
}
})();
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 62703208..dfa783e9 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
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -21,9 +22,9 @@
.factory('horizon.dashboard.project.lbaasv2.pools.actions.delete', deleteService);
deleteService.$inject = [
- '$q',
+ 'horizon.dashboard.project.lbaasv2.pools.resourceType',
+ 'horizon.framework.util.actions.action-result.service',
'$location',
- '$route',
'horizon.framework.widgets.modal.deleteModalService',
'horizon.app.core.openstack-service-api.lbaasv2',
'horizon.app.core.openstack-service-api.policy',
@@ -33,22 +34,28 @@
/**
* @ngDoc factory
* @name horizon.dashboard.project.lbaasv2.pools.actions.deleteService
+ *
* @description
* Brings up the delete pool confirmation modal dialog.
* On submit, deletes selected pool.
* On cancel, does nothing.
- * @param $q The angular service for promises.
+ *
+ * @param resourceType The pool resource type.
+ * @param actionResultService The horizon action result service.
* @param $location The angular $location service.
- * @param $route The angular $route service.
* @param deleteModal The horizon delete modal service.
* @param api The LBaaS v2 API service.
* @param policy The horizon policy service.
* @param gettext The horizon gettext function for translation.
- * @returns The load balancers table delete service.
+ *
+ * @returns The pool delete service.
*/
- function deleteService($q, $location, $route, deleteModal, api, policy, gettext) {
- var loadbalancerId, listenerId, statePromise;
+ function deleteService(
+ resourceType, actionResultService, $location,
+ deleteModal, api, policy, gettext
+ ) {
+ var loadbalancerId, listenerId;
var context = {
labels: {
title: gettext('Confirm Delete Pool'),
@@ -66,47 +73,50 @@
var service = {
perform: perform,
allowed: allowed,
- init: init
+ deleteResult: deleteResult // exposed just for testing
};
return service;
//////////////
- function init(_loadbalancerId_, _listenerId_, _statePromise_) {
- loadbalancerId = _loadbalancerId_;
- listenerId = _listenerId_;
- statePromise = _statePromise_;
- return service;
- }
-
- function perform(item) {
- deleteModal.open({ $emit: actionComplete }, [item], context);
- }
-
function allowed(/*item*/) {
- return $q.all([
- statePromise,
- // This rule is made up and should therefore always pass. I assume at some point there
- // will be a valid rule similar to this that we will want to use.
- policy.ifAllowed({ rules: [['neutron', 'delete_pool']] })
- ]);
+ // This rule is made up and should therefore always pass. I assume at some point there
+ // will be a valid rule similar to this that we will want to use.
+ return policy.ifAllowed({ rules: [['neutron', 'delete_pool']] });
+ }
+
+ function perform(items, scope) {
+ var pools = angular.isArray(items) ? items : [items];
+ pools.map(function(item) {
+ loadbalancerId = item.loadbalancerId;
+ listenerId = item.listenerId;
+ });
+ return deleteModal.open(scope, pools, context).then(deleteResult);
+ }
+
+ function deleteResult(deleteModalResult) {
+ // To make the result of this action generically useful, reformat the return
+ // from the deleteModal into a standard form
+ var actionResult = actionResultService.getActionResult();
+ deleteModalResult.pass.forEach(function markDeleted(item) {
+ actionResult.deleted(resourceType, item.context.id);
+ });
+ deleteModalResult.fail.forEach(function markFailed(item) {
+ actionResult.failed(resourceType, item.context.id);
+ });
+
+ if (actionResult.result.failed.length === 0 && actionResult.result.deleted.length > 0) {
+ var path = 'project/load_balancer/' + loadbalancerId +
+ '/listeners/' + listenerId;
+ $location.path(path);
+ }
+ return actionResult.result;
}
function deleteItem(id) {
return api.deletePool(id, true);
}
- function actionComplete(eventType) {
- if (eventType === context.failedEvent) {
- // Error, reload page
- $route.reload();
- } else {
- // Success, go back to listener details page
- var path = 'project/load_balancer/' + loadbalancerId + '/listeners/' + listenerId;
- $location.path(path);
- }
- }
-
}
})();
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 736b3e00..174a3a15 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
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -17,138 +18,87 @@
'use strict';
describe('LBaaS v2 Pool Delete Service', function() {
- var service, policy, modal, lbaasv2Api, $scope, $location, $q, toast, pool;
-
- function allowed(item) {
- spyOn(policy, 'ifAllowed').and.returnValue(makePromise());
- var promise = service.allowed(item);
- var allowed;
- promise.then(function() {
- allowed = true;
- }, function() {
- allowed = false;
- });
- $scope.$apply();
- expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'delete_pool']]});
- return allowed;
- }
-
- function makePromise(reject) {
- var def = $q.defer();
- def[reject ? 'reject' : 'resolve']();
- return def.promise;
- }
-
- function isActionable(id) {
- if (id === 'active') {
- return $q.when();
- } else {
- return $q.reject();
- }
- }
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
+ beforeEach(module('horizon.app.core'));
beforeEach(module('horizon.dashboard.project.lbaasv2'));
+ beforeEach(module('horizon.framework'));
- beforeEach(function() {
- pool = { id: '1', name: 'Pool1' };
- });
+ var deleteModalService, service, lbaasv2API, policyAPI, $location;
- beforeEach(module(function($provide) {
- $provide.value('$uibModal', {
- open: function() {
- return {
- result: makePromise()
- };
- }
- });
- $provide.value('horizon.app.core.openstack-service-api.lbaasv2', {
- deletePool: function() {
- return makePromise();
- }
- });
- $provide.value('$location', {
- path: function() {
- return '';
- }
- });
- }));
-
- beforeEach(inject(function ($injector) {
- policy = $injector.get('horizon.app.core.openstack-service-api.policy');
- lbaasv2Api = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
- modal = $injector.get('horizon.framework.widgets.modal.deleteModalService');
- $scope = $injector.get('$rootScope').$new();
- $location = $injector.get('$location');
- $q = $injector.get('$q');
- toast = $injector.get('horizon.framework.widgets.toast.service');
+ beforeEach(inject(function($injector) {
service = $injector.get('horizon.dashboard.project.lbaasv2.pools.actions.delete');
- service.init('1', '2', isActionable('active'));
- $scope.$apply();
+ lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
+ deleteModalService = $injector.get('horizon.framework.widgets.modal.deleteModalService');
+ policyAPI = $injector.get('horizon.app.core.openstack-service-api.policy');
+ $location = $injector.get('$location');
}));
- it('should have the "allowed" and "perform" functions', function() {
- expect(service.allowed).toBeDefined();
- expect(service.perform).toBeDefined();
+ describe('perform method', function() {
+ beforeEach(function () {
+ // just need for this to return something that looks like a promise but does nothing
+ spyOn(deleteModalService, 'open').and.returnValue({then: angular.noop});
+ });
+
+ it('should open the modal with correct label', function () {
+ service.perform({name: 'spam'});
+ var labels = deleteModalService.open.calls.argsFor(0)[2].labels;
+ expect(deleteModalService.open).toHaveBeenCalled();
+ angular.forEach(labels, function eachLabel(label) {
+ expect(label.toLowerCase()).toContain('pool');
+ });
+ });
+
+ it('should open the delete modal with correct entities', function () {
+ service.perform([{name: 'one'}, {name: 'two'}]);
+ var entities = deleteModalService.open.calls.argsFor(0)[1];
+ expect(deleteModalService.open).toHaveBeenCalled();
+ expect(entities.length).toEqual(2);
+ });
+
+ it('should pass in a function that deletes a pool', function () {
+ spyOn(lbaasv2API, 'deletePool').and.callFake(angular.noop);
+ service.perform({id: 1, name: 'one'});
+ var contextArg = deleteModalService.open.calls.argsFor(0)[2];
+ var deleteFunction = contextArg.deleteEntity;
+ deleteFunction(1);
+ expect(lbaasv2API.deletePool).toHaveBeenCalledWith(1, true);
+ });
});
- it('should allow deleting pool from load balancer in ACTIVE state', function() {
- expect(allowed()).toBe(true);
- });
-
- it('should not allow deleting pool from load balancer in a PENDING state', function() {
- service.init('1', '2', isActionable('pending'));
- expect(allowed()).toBe(false);
- });
-
- it('should open the delete modal', function() {
- spyOn(modal, 'open');
- service.perform(pool);
- $scope.$apply();
- expect(modal.open.calls.count()).toBe(1);
- var args = modal.open.calls.argsFor(0);
- expect(args.length).toBe(3);
- expect(args[0]).toEqual({ $emit: jasmine.any(Function) });
- expect(args[1]).toEqual([pool]);
- expect(args[2]).toEqual(jasmine.objectContaining({
- labels: jasmine.any(Object),
- deleteEntity: jasmine.any(Function)
- }));
- expect(args[2].labels.title).toBe('Confirm Delete Pool');
- });
-
- it('should pass function to modal that deletes the pool', function() {
- spyOn(modal, 'open').and.callThrough();
- spyOn(lbaasv2Api, 'deletePool').and.callThrough();
- service.perform(pool);
- $scope.$apply();
- expect(lbaasv2Api.deletePool.calls.count()).toBe(1);
- expect(lbaasv2Api.deletePool).toHaveBeenCalledWith('1', true);
- });
-
- it('should show message if any items fail to be deleted', function() {
- spyOn(modal, 'open').and.callThrough();
- spyOn(lbaasv2Api, 'deletePool').and.returnValue(makePromise(true));
- spyOn(toast, 'add');
- service.perform(pool);
- $scope.$apply();
- expect(modal.open).toHaveBeenCalled();
- expect(lbaasv2Api.deletePool.calls.count()).toBe(1);
- expect(toast.add).toHaveBeenCalledWith('error', 'The following pool could not ' +
- 'be deleted: Pool1.');
- });
-
- it('should return to listener details after delete', function() {
+ it('should handle the action result properly', function() {
spyOn($location, 'path');
- spyOn(toast, 'add');
- service.perform(pool);
- $scope.$apply();
- expect($location.path).toHaveBeenCalledWith('project/load_balancer/1/listeners/2');
- expect(toast.add).toHaveBeenCalledWith('success', 'Deleted pool: Pool1.');
+ spyOn(deleteModalService, 'open').and.returnValue({then: angular.noop});
+ spyOn(lbaasv2API, 'deletePool').and.callFake(angular.noop);
+ service.perform({loadbalancerId: 1, listenerId: 2, id: 1, name: 'one'});
+ var result = service.deleteResult({
+ fail: [],
+ pass: [{
+ context: {
+ id: 1
+ }
+ }]
+ });
+ var path = 'project/load_balancer/1/listeners/2';
+ 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');
+ service.allowed();
+ expect(policyAPI.ifAllowed).toHaveBeenCalled();
+ });
+ }); // end of allowed
+
+ }); // end of delete
+
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/edit/edit.action.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/edit/edit.action.service.js
index 40f81fb1..9b8eaed5 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/edit/edit.action.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/edit/edit.action.service.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -21,8 +22,8 @@
.factory('horizon.dashboard.project.lbaasv2.pools.actions.edit', editService);
editService.$inject = [
- '$q',
- '$route',
+ 'horizon.dashboard.project.lbaasv2.pools.resourceType',
+ 'horizon.framework.util.actions.action-result.service',
'horizon.dashboard.project.lbaasv2.workflow.modal',
'horizon.app.core.openstack-service-api.policy',
'horizon.framework.util.i18n.gettext'
@@ -30,52 +31,39 @@
/**
* @ngDoc factory
- * @name horizon.dashboard.project.lbaasv2.listeners.actions.editService
+ * @name horizon.dashboard.project.lbaasv2.pools.actions.editService
+ *
* @description
* Provides the service for editing a pool resource.
- * @param $q The angular service for promises.
- * @param $route The angular $route service.
+ *
+ * @param resourceType The pool resource type.
+ * @param actionResultService The horizon action result service.
* @param workflowModal The LBaaS workflow modal service.
* @param policy The horizon policy service.
* @param gettext The horizon gettext function for translation.
- * @returns The load balancers pool edit service.
+ *
+ * @returns The pool edit service.
*/
function editService(
- $q, $route, workflowModal, policy, gettext
+ resourceType, actionResultService, workflowModal, policy, gettext
) {
- var statePromise;
- var edit = workflowModal.init({
+ return workflowModal.init({
controller: 'EditPoolWizardController',
message: gettext('The pool has been updated.'),
- handle: onEdit,
+ handle: handle,
allowed: allowed
});
- var service = {
- init: init,
- edit: edit
- };
-
- return service;
-
- //////////////
-
- function init(_statePromise_) {
- statePromise = _statePromise_;
- return service;
- }
-
function allowed(/*item*/) {
- return $q.all([
- statePromise,
- policy.ifAllowed({ rules: [['neutron', 'update_pool']] })
- ]);
+ return policy.ifAllowed({ rules: [['neutron', 'update_pool']] });
}
- function onEdit(/*response*/) {
- $route.reload();
+ function handle(response) {
+ return actionResultService.getActionResult()
+ .updated(resourceType, response.config.data.pool.id)
+ .result;
}
}
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/edit/edit.action.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/edit/edit.action.service.spec.js
index 66fceaa4..6528f2b8 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/edit/edit.action.service.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/edit/edit.action.service.spec.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -17,85 +18,38 @@
'use strict';
describe('LBaaS v2 Edit Pool Action Service', function() {
- var scope, $q, $route, policy, init, editPoolService, defer;
+ var policy, service;
- function allowed(item) {
- spyOn(policy, 'ifAllowed').and.returnValue(true);
- var promise = editPoolService.edit.allowed(item);
- var allowed;
- promise.then(function() {
- allowed = true;
- }, function() {
- allowed = false;
- });
- scope.$apply();
- expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'update_pool']]});
- return allowed;
- }
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
beforeEach(module('horizon.dashboard.project.lbaasv2'));
beforeEach(module(function($provide) {
- var response = {
- data: {
- id: '9012'
- }
- };
- var modal = {
+ $provide.value('$modal', {
open: function() {
return {
result: {
then: function(func) {
- func(response);
+ func({ data: { id: 'pool1' } });
}
}
};
}
- };
- $provide.value('$uibModal', modal);
+ });
}));
beforeEach(inject(function ($injector) {
- scope = $injector.get('$rootScope').$new();
- $q = $injector.get('$q');
policy = $injector.get('horizon.app.core.openstack-service-api.policy');
- $route = $injector.get('$route');
- editPoolService = $injector.get(
- 'horizon.dashboard.project.lbaasv2.pools.actions.edit');
- init = editPoolService.init;
- defer = $q.defer();
+ service = $injector.get('horizon.dashboard.project.lbaasv2.pools.actions.edit');
}));
- it('should define the correct service properties', function() {
- expect(editPoolService.init).toBeDefined();
- expect(editPoolService.edit).toBeDefined();
+ it('should check policy to allow editing a pool', function() {
+ spyOn(policy, 'ifAllowed').and.returnValue(true);
+ expect(service.allowed()).toBe(true);
+ expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'update_pool']]});
});
- it('should have the "allowed" and "perform" functions', function() {
- expect(editPoolService.edit.allowed).toBeDefined();
- expect(editPoolService.edit.perform).toBeDefined();
- });
-
- it('should allow editing a pool under an ACTIVE load balancer', function() {
- defer.resolve();
- init(defer.promise);
- expect(allowed({default_pool_id: '1234'})).toBe(true);
- });
-
- it('should not allow editing a pool under an NON-ACTIVE load balancer', function() {
- defer.reject();
- init(defer.promise);
- expect(allowed({default_pool_id: '1234'})).toBe(false);
- });
-
- it('should redirect after edit', function() {
- spyOn($route, 'reload').and.callThrough();
- editPoolService.edit.perform();
- expect($route.reload).toHaveBeenCalled();
+ it('should handle the action result properly', function() {
+ var result = service.handle({config: {data: {pool: {id: 1}}}});
+ expect(result.updated[0].id).toBe(1);
});
});
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/row-actions.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/row-actions.service.js
deleted file mode 100644
index a4f345c4..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/row-actions.service.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.pools')
- .factory('horizon.dashboard.project.lbaasv2.pools.actions.rowActions',
- rowActions);
-
- rowActions.$inject = [
- 'horizon.framework.util.i18n.gettext',
- 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
- 'horizon.dashboard.project.lbaasv2.pools.actions.edit',
- 'horizon.dashboard.project.lbaasv2.pools.actions.delete',
- 'horizon.dashboard.project.lbaasv2.healthmonitors.actions.create'
- ];
-
- /**
- * @ngdoc service
- * @ngname horizon.dashboard.project.lbaasv2.pools.actions.rowActions
- *
- * @description
- * Provides the service for the pool row actions.
- *
- * @param gettext The horizon gettext function for translation.
- * @param loadBalancersService The LBaaS v2 load balancers service.
- * @param editService The LBaaS v2 pools delete service.
- * @param deleteService The LBaaS v2 pools delete service.
- * @param createService The LBaaS v2 health monitor create service.
- * @returns Pool row actions service object.
- */
-
- function rowActions(gettext, loadBalancersService, editService, deleteService, createService) {
- var loadBalancerIsActionable, loadbalancerId, listenerId;
-
- var service = {
- actions: actions,
- init: init
- };
-
- return service;
-
- ///////////////
-
- function init(_loadbalancerId_, _listenerId_) {
- loadbalancerId = _loadbalancerId_;
- listenerId = _listenerId_;
- loadBalancerIsActionable = loadBalancersService.isActionable(loadbalancerId);
- return service;
- }
-
- function actions() {
- return [{
- service: editService.init(loadBalancerIsActionable).edit,
- template: {
- text: gettext('Edit')
- }
- },{
- service: createService.init(loadbalancerId, listenerId, loadBalancerIsActionable).create,
- template: {
- text: gettext('Create Health Monitor')
- }
- },{
- service: deleteService.init(loadbalancerId, listenerId, loadBalancerIsActionable),
- template: {
- text: gettext('Delete Pool'),
- type: 'delete'
- }
- }];
- }
- }
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/row-actions.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/row-actions.service.spec.js
deleted file mode 100644
index 382cb87b..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/actions/row-actions.service.spec.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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 Pools Row Actions Service', function() {
- var actions;
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
- beforeEach(module('horizon.dashboard.project.lbaasv2'));
-
- beforeEach(inject(function ($injector) {
- var rowActionsService = $injector.get(
- 'horizon.dashboard.project.lbaasv2.pools.actions.rowActions');
- actions = rowActionsService.init('1', '2').actions();
- var loadbalancerService = $injector.get(
- 'horizon.dashboard.project.lbaasv2.loadbalancers.service');
- spyOn(loadbalancerService, 'isActionable').and.returnValue(true);
- }));
-
- it('should define correct table row actions', function() {
- expect(actions.length).toBe(3);
- expect(actions[0].template.text).toBe('Edit');
- expect(actions[1].template.text).toBe('Create Health Monitor');
- expect(actions[2].template.text).toBe('Delete Pool');
- });
-
- it('should have the "allowed" and "perform" functions', function() {
- actions.forEach(function(action) {
- expect(action.service.allowed).toBeDefined();
- expect(action.service.perform).toBeDefined();
- });
- });
-
- });
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/detail.controller.js
deleted file mode 100644
index 4f0e1883..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/detail.controller.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.pools')
- .controller('PoolDetailController', PoolDetailController);
-
- PoolDetailController.$inject = [
- 'horizon.app.core.openstack-service-api.lbaasv2',
- 'horizon.dashboard.project.lbaasv2.pools.actions.rowActions',
- '$routeParams',
- 'horizon.framework.util.i18n.gettext',
- '$window',
- '$scope',
- '$q'
- ];
-
- /**
- * @ngdoc controller
- * @name PoolDetailController
- *
- * @description
- * Controller for the LBaaS v2 pool detail page.
- *
- * @param api The LBaaS v2 API service.
- * @param rowActions The LBaaS v2 pool row actions service.
- * @param $routeParams The angular $routeParams service.
- * @param gettext The horizon gettext function for translation.
- * @param $window Angular's reference to the browser window object.
- * @param $scope The angular scope object.
- * @param $q The angular service for promises.
- * @returns undefined
- */
-
- function PoolDetailController(api, rowActions, $routeParams, gettext, $window, $scope, $q) {
- var ctrl = this;
-
- ctrl.loading = true;
- ctrl.error = false;
- ctrl.loadBalancerAlgorithm = {
- ROUND_ROBIN: gettext('Round Robin'),
- LEAST_CONNECTIONS: gettext('Least Connections'),
- SOURCE_IP: gettext('Source IP')
- };
- ctrl.actions = rowActions.init($routeParams.loadbalancerId, $routeParams.listenerId).actions;
- ctrl.membersTabActive = $window.membersTabActive;
-
- init();
-
- ////////////////////////////////
-
- function init() {
- ctrl.pool = null;
- ctrl.listener = null;
- ctrl.loadbalancer = null;
- ctrl.loading = true;
- ctrl.error = false;
- $q.all([
- api.getPool($routeParams.poolId)
- .then(success('pool'), fail('pool')),
- api.getListener($routeParams.listenerId)
- .then(success('listener'), fail('listener')),
- api.getLoadBalancer($routeParams.loadbalancerId)
- .then(success('loadbalancer'), fail('loadbalancer'))
- ]).then(postInit, initError);
- }
-
- function success(property) {
- return angular.bind(null, function setProp(property, response) {
- ctrl[property] = response.data;
- }, property);
- }
-
- function fail(property) {
- return angular.bind(null, function setProp(property, error) {
- ctrl[property] = null;
- throw error;
- }, property);
- }
-
- function postInit() {
- ctrl.loading = false;
- }
-
- function initError() {
- ctrl.loading = false;
- ctrl.error = true;
- }
-
- // Save the active state of the members tab in the global window object so it can stay
- // active after reloading the route following an action.
- $scope.$watch(function() {
- return ctrl.membersTabActive;
- }, function(active) {
- $window.membersTabActive = active;
- });
-
- }
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/detail.controller.spec.js
deleted file mode 100644
index 894383db..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/detail.controller.spec.js
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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 Pool Detail Controller', function() {
- var lbaasv2API, $scope, $window, $controller, apiFail, qAllFail;
-
- function fakePromise(data, reject) {
- return {
- then: function(success, fail) {
- if (reject) {
- fail();
- } else {
- success({ data: data });
- }
- return fakePromise();
- }
- };
- }
-
- function fakeAPI() {
- return fakePromise('foo', apiFail);
- }
-
- function loadbalancerAPI() {
- return fakePromise({ provisioning_status: 'ACTIVE' });
- }
-
- function qAll() {
- return fakePromise(null, qAllFail);
- }
-
- function createController() {
- return $controller('PoolDetailController', {
- $scope: $scope,
- $window: $window,
- $routeParams: {
- loadbalancerId: 'loadbalancerId',
- listenerId: 'listenerId',
- poolId: 'poolId'
- }
- });
- }
-
- ///////////////////////
-
- beforeEach(module('horizon.framework.util'));
- beforeEach(module('horizon.framework.widgets'));
- beforeEach(module('horizon.framework.conf'));
- beforeEach(module('horizon.app.core.openstack-service-api'));
- beforeEach(module('horizon.dashboard.project.lbaasv2'));
-
- beforeEach(module(function($provide) {
- apiFail = false;
- qAllFail = false;
-
- $provide.value('$q', { all: qAll });
- }));
-
- beforeEach(inject(function($injector) {
- lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
- spyOn(lbaasv2API, 'getPool').and.callFake(fakeAPI);
- spyOn(lbaasv2API, 'getListener').and.callFake(fakeAPI);
- spyOn(lbaasv2API, 'getLoadBalancer').and.callFake(loadbalancerAPI);
- $scope = $injector.get('$rootScope').$new();
- $window = {};
- $controller = $injector.get('$controller');
- }));
-
- it('should invoke lbaasv2 apis', function() {
- var ctrl = createController();
- expect(lbaasv2API.getPool).toHaveBeenCalledWith('poolId');
- expect(lbaasv2API.getListener).toHaveBeenCalledWith('listenerId');
- expect(lbaasv2API.getLoadBalancer).toHaveBeenCalledWith('loadbalancerId');
- expect(ctrl.loadbalancer).toEqual({provisioning_status: 'ACTIVE'});
- expect(ctrl.listener).toBe('foo');
- expect(ctrl.pool).toBe('foo');
- });
-
- it('should define mapping for the load balancer algorithm', function() {
- var ctrl = createController();
- expect(ctrl.loadBalancerAlgorithm).toBeDefined();
- });
-
- it('should save changes to members tab active state', function() {
- var ctrl = createController();
- expect($window.membersTabActive).toBeUndefined();
- expect(ctrl.membersTabActive).toBeUndefined();
- ctrl.membersTabActive = true;
- $scope.$apply();
- expect($window.membersTabActive).toBe(true);
- ctrl.membersTabActive = false;
- $scope.$apply();
- expect($window.membersTabActive).toBe(false);
- });
-
- it('should throw error on API fail', function() {
- apiFail = true;
- var init = function() {
- createController();
- };
- expect(init).toThrow();
- });
-
- it('should set error state if any APIs fail', function() {
- qAllFail = true;
- var ctrl = createController();
- expect(ctrl.loading).toBe(false);
- expect(ctrl.error).toBe(true);
- });
-
- });
-
-})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/detail.html
deleted file mode 100644
index 4dc88f0f..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/detail.html
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
-
-
-
-
-
-
- - Protocol
- - {$ ::ctrl.pool.protocol $}
- - Load Balancer Algorithm
- - {$ ctrl.pool.lb_algorithm | decode:ctrl.loadBalancerAlgorithm $}
- - Session Persistence
- - {$ ctrl.pool.session_persistence | noValue:('None' | translate) $}
- - Admin State Up
- - {$ ctrl.pool.admin_state_up | yesno $}
- - Health Monitor ID
- -
-
- {$ ::ctrl.pool.health_monitor_id $}
-
-
- {$ 'None' | translate $}
-
-
- - Pool ID
- - {$ ::ctrl.pool.id $}
- - Project ID
- - {$ ::ctrl.pool.project_id $}
- - Created At
- - {$ ::ctrl.pool.created_at $}
- - Updated At
- - {$ ::ctrl.pool.updated_at $}
-
-
-
-
-
-
-
-
-
-
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
new file mode 100644
index 00000000..696a3ff5
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.js
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
+ *
+ * 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.pools')
+ .controller('PoolDetailController', PoolDetailController);
+
+ PoolDetailController.$inject = [
+ 'loadbalancer',
+ 'listener',
+ 'pool',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
+ 'horizon.dashboard.project.lbaasv2.pools.resourceType',
+ 'horizon.framework.conf.resource-type-registry.service',
+ 'horizon.framework.widgets.modal-wait-spinner.service',
+ '$q'
+ ];
+
+ /**
+ * @ngdoc controller
+ * @name PoolDetailController
+ *
+ * @description
+ * Controller for the LBaaS v2 pool detail page.
+ *
+ * @param loadbalancer The loadbalancer object.
+ * @param listener The listener object.
+ * @param pool The pool object.
+ * @param loadBalancersService The LBaaS v2 load balancers service.
+ * @param resourceType The load balancer resource type.
+ * @param typeRegistry The horizon type registry service.
+ * @param spinnerService The horizon modal wait spinner service.
+ * @param $q The angular service for promises.
+ *
+ * @returns undefined
+ */
+
+ function PoolDetailController(
+ loadbalancer, listener, pool, loadBalancersService,
+ resourceType, typeRegistry, spinnerService, $q
+ ) {
+ var ctrl = this;
+
+ ctrl.operatingStatus = loadBalancersService.operatingStatus;
+ ctrl.provisioningStatus = loadBalancersService.provisioningStatus;
+ ctrl.loadBalancerAlgorithm = loadBalancersService.loadBalancerAlgorithm;
+ ctrl.loadbalancer = loadbalancer;
+ ctrl.listener = listener;
+ ctrl.pool = pool;
+ ctrl.listFunctionExtraParams = {
+ loadbalancerId: ctrl.loadbalancer.id,
+ listenerId: ctrl.listener.id,
+ poolId: ctrl.pool.id
+ };
+ ctrl.resourceType = typeRegistry.getResourceType(resourceType);
+ ctrl.context = {};
+ ctrl.context.identifier = pool.id;
+
+ ctrl.resultHandler = actionResultHandler;
+
+ function actionResultHandler(returnValue) {
+ return $q.when(returnValue, actionSuccessHandler);
+ }
+
+ function loadData(response) {
+ spinnerService.hideModalSpinner();
+ ctrl.showDetails = true;
+ ctrl.resourceType.initActions();
+ ctrl.pool = response.data;
+ ctrl.pool.loadbalancerId = ctrl.loadbalancer.id;
+ ctrl.pool.listenerId = ctrl.listener.id;
+ }
+
+ function actionSuccessHandler(result) {
+ // The action has completed (for whatever "complete" means to that
+ // action. Notice the view doesn't really need to know the semantics of the
+ // particular action because the actions return data in a standard form.
+ // That return includes the id and type of each created, updated, deleted
+ // and failed item.
+ // Currently just refreshes the display each time.
+ if (result) {
+ spinnerService.showModalSpinner(gettext('Please Wait'));
+ ctrl.showDetails = false;
+ ctrl.context.loadPromise = ctrl.resourceType.load(ctrl.context.identifier);
+ ctrl.context.loadPromise.then(loadData);
+ }
+ }
+ }
+
+})();
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
new file mode 100644
index 00000000..92376332
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.spec.js
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
+ *
+ * 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 Pool Detail Controller', function() {
+ var deferred, service, ctrl, scope, $timeout, $q, actionResultService;
+
+ ///////////////////////
+
+ beforeEach(module('horizon.dashboard.project.lbaasv2'));
+
+ beforeEach(module(function($provide) {
+ $provide.value('$uibModal', {});
+ }));
+
+ beforeEach(inject(function($controller, $rootScope, _$q_, _$timeout_) {
+ $q = _$q_;
+ deferred = $q.defer();
+ service = {
+ getResourceType: function() {
+ return {
+ load: function() { return deferred.promise; },
+ parsePath: function() { return 'my-context'; },
+ itemName: function() { return 'A name'; },
+ initActions: angular.noop
+ };
+ },
+ getDefaultDetailsTemplateUrl: angular.noop
+ };
+ actionResultService = {
+ getIdsOfType: function() { return []; }
+ };
+ $timeout = _$timeout_;
+ scope = $rootScope.$new();
+ ctrl = $controller('PoolDetailController', {
+ $scope: scope,
+ loadbalancer: { id: '123' },
+ listener: { id: '123' },
+ 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
+ }
+ });
+ }));
+
+ it('should create a controller', function() {
+ expect(ctrl).toBeDefined();
+ expect(ctrl.loadbalancer).toBeDefined();
+ expect(ctrl.listener).toBeDefined();
+ expect(ctrl.pool).toBeDefined();
+ });
+
+ describe('resultHandler', function() {
+
+ it('handles empty results', function() {
+ var result = $q.defer();
+ result.resolve({});
+ ctrl.resultHandler(result.promise);
+ $timeout.flush();
+ expect(ctrl.showDetails).not.toBe(true);
+ });
+
+ it('handles falsy results', function() {
+ var result = $q.defer();
+ result.resolve(false);
+ ctrl.resultHandler(result.promise);
+ $timeout.flush();
+ expect(ctrl.showDetails).not.toBe(true);
+ });
+
+ it('handles matched results', function() {
+ spyOn(actionResultService, 'getIdsOfType').and.returnValue([1, 2, 3]);
+ var result = $q.defer();
+ result.resolve({some: 'thing'});
+ ctrl.resultHandler(result.promise);
+ deferred.resolve({data: {some: 'data'}});
+ $timeout.flush();
+ expect(ctrl.showDetails).toBe(true);
+ });
+
+ });
+
+ });
+
+})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.html
new file mode 100644
index 00000000..eaf0544e
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.html
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/drawer.html b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/drawer.html
new file mode 100644
index 00000000..fb0dab48
--- /dev/null
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/drawer.html
@@ -0,0 +1,9 @@
+
+
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/pools.module.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/pools.module.js
index ee56bb41..1f884b4a 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/pools.module.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/pools.module.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -26,6 +27,156 @@
*/
angular
- .module('horizon.dashboard.project.lbaasv2.pools', []);
+ .module('horizon.dashboard.project.lbaasv2.pools', [])
+ .constant('horizon.dashboard.project.lbaasv2.pools.resourceType',
+ 'OS::Octavia::Pool')
+ .run(run);
+
+ run.$inject = [
+ 'horizon.framework.conf.resource-type-registry.service',
+ 'horizon.dashboard.project.lbaasv2.basePath',
+ 'horizon.dashboard.project.lbaasv2.loadbalancers.service',
+ 'horizon.dashboard.project.lbaasv2.pools.actions.create',
+ 'horizon.dashboard.project.lbaasv2.pools.actions.edit',
+ 'horizon.dashboard.project.lbaasv2.pools.actions.delete',
+ 'horizon.dashboard.project.lbaasv2.pools.resourceType'
+ ];
+
+ function run(
+ registry,
+ basePath,
+ loadBalancerService,
+ createService,
+ editService,
+ deleteService,
+ resourceType
+ ) {
+ var poolResourceType = registry.getResourceType(resourceType);
+
+ poolResourceType
+ .setNames(gettext('Pool'), gettext('Pools'))
+ .setSummaryTemplateUrl(basePath + 'pools/details/drawer.html')
+ .setProperties(poolProperties(loadBalancerService))
+ .setListFunction(loadBalancerService.getPoolsPromise)
+ .setLoadFunction(loadBalancerService.getPoolPromise)
+ .tableColumns
+ .append({
+ id: 'name',
+ priority: 1,
+ sortDefault: true,
+ urlFunction: loadBalancerService.getPoolDetailsPath
+ })
+ .append({
+ id: 'protocol',
+ priority: 1
+ })
+ .append({
+ id: 'lb_algorithm',
+ priority: 1
+ })
+ .append({
+ id: 'operating_status',
+ priority: 1
+ })
+ .append({
+ id: 'provisioning_status',
+ priority: 1
+ })
+ .append({
+ id: 'admin_state_up',
+ priority: 1
+ });
+
+ poolResourceType.itemActions
+ .append({
+ id: 'poolEdit',
+ service: editService,
+ template: {
+ text: gettext('Edit Pool')
+ }
+ })
+ .append({
+ id: 'poolDelete',
+ service: deleteService,
+ template: {
+ text: gettext('Delete Pool'),
+ type: 'delete'
+ }
+ });
+
+ poolResourceType.globalActions
+ .append({
+ id: 'poolCreate',
+ service: createService,
+ template: {
+ type: 'create',
+ text: gettext('Create Pool')
+ }
+ });
+
+ poolResourceType.batchActions
+ .append({
+ id: 'poolBatchDelete',
+ service: deleteService,
+ template: {
+ text: gettext('Delete Pools'),
+ type: 'delete-selected'
+ }
+ });
+ }
+
+ function poolProperties(loadBalancerService) {
+ return {
+ id: gettext('ID'),
+ name: {
+ label: gettext('Name'),
+ filters: ['noName']
+ },
+ description: {
+ label: gettext('Description'),
+ filters: ['noValue']
+ },
+ provisioning_status: {
+ label: gettext('Provisioning Status'),
+ values: loadBalancerService.provisioningStatus
+ },
+ operating_status: {
+ label: gettext('Operating Status'),
+ values: loadBalancerService.operatingStatus
+ },
+ admin_state_up: {
+ label: gettext('Admin State Up'),
+ filters: ['yesno']
+ },
+ protocol: gettext('Protocol'),
+ lb_algorithm: {
+ label: gettext('Algorithm'),
+ values: loadBalancerService.loadBalancerAlgorithm
+ },
+ session_persistence: {
+ label: gettext('Session Persistence'),
+ filters: [
+ 'json',
+ loadBalancerService.nullFilter
+ ]
+ },
+ health_monitor_id: {
+ label: gettext('Health Monitor ID'),
+ filters: ['noName']
+ },
+ project_id: gettext('Project ID'),
+ created_at: {
+ label: gettext('Created At'),
+ filters: ['noValue']
+ },
+ updated_at: {
+ label: gettext('Updated At'),
+ filters: ['noValue']
+ },
+ loadbalancers: gettext('Load Balancers'),
+ listeners: gettext('Listeners'),
+ members: gettext('Members')
+ };
+ }
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/pools.module.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/pools.module.spec.js
index 58497c48..4a2c226b 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/pools.module.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/pools.module.spec.js
@@ -1,5 +1,6 @@
/*
* Copyright 2016 IBM Corp.
+ * Copyright 2017 Walmart.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -22,4 +23,46 @@
});
});
+ describe('LBaaS v2 Pools Registry', function () {
+ var registry, resourceType;
+
+ beforeEach(module('horizon.dashboard.project.lbaasv2'));
+
+ beforeEach(inject(function($injector) {
+ resourceType = $injector.get('horizon.dashboard.project.lbaasv2.pools.resourceType');
+ registry = $injector.get('horizon.framework.conf.resource-type-registry.service');
+ }));
+
+ it('should define resourceType', function () {
+ expect(resourceType).toBeDefined();
+ });
+
+ it('should register item actions', function () {
+ var actions = registry.getResourceType(resourceType).itemActions;
+ expect(actionHasId(actions, 'poolEdit')).toBe(true);
+ expect(actionHasId(actions, 'poolDelete')).toBe(true);
+ });
+
+ it('should register global actions', function () {
+ var actions = registry.getResourceType(resourceType).globalActions;
+ expect(actionHasId(actions, 'poolCreate')).toBe(true);
+ });
+
+ it('should register batch actions', function () {
+ var actions = registry.getResourceType(resourceType).batchActions;
+ expect(actionHasId(actions, 'poolBatchDelete')).toBe(true);
+ });
+
+ function actionHasId(list, value) {
+ return list.filter(matchesId).length === 1;
+
+ function matchesId(action) {
+ if (action.id === value) {
+ return true;
+ }
+ }
+ }
+
+ });
+
})();
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/widgets/detail/detail-status.directive.js b/octavia_dashboard/static/dashboard/project/lbaasv2/widgets/detail/detail-status.directive.js
deleted file mode 100644
index 24cb0f91..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/widgets/detail/detail-status.directive.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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')
- .directive('detailStatus', detailStatus);
-
- detailStatus.$inject = [
- 'horizon.dashboard.project.lbaasv2.basePath'
- ];
-
- /**
- * @ngdoc directive
- * @name horizon.dashboard.project.lbaasv2:detailStatus
- * @description
- * The `detailStatus` directive provides a status indicator while loading detail pages. It will
- * show a loading indicator while the page is loading and an error indicator if there is an
- * error loading the page.
- * @restrict E
- *
- * @example
- * ```
- *
- * ```
- */
-
- function detailStatus(basePath) {
- var directive = {
- restrict: 'E',
- templateUrl: basePath + 'widgets/detail/detail-status.html',
- scope: {
- loading: '=',
- error: '='
- }
- };
- return directive;
- }
-}());
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/widgets/detail/detail-status.directive.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/widgets/detail/detail-status.directive.spec.js
deleted file mode 100644
index c26c5fde..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/widgets/detail/detail-status.directive.spec.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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';
-
- function digestMarkup(scope, compile, markup) {
- var element = angular.element(markup);
- compile(element)(scope);
- scope.$apply();
- return element;
- }
-
- describe('detailStatus directive', function() {
- var $scope, $compile, markup, ctrl;
-
- beforeEach(module('templates'));
- beforeEach(module('horizon.dashboard.project.lbaasv2'));
-
- beforeEach(inject(function($injector) {
- $compile = $injector.get('$compile');
- $scope = $injector.get('$rootScope').$new();
- ctrl = {
- loading: true,
- error: false
- };
- $scope.ctrl = ctrl;
- markup = '';
- }));
-
- it('initially shows loading status', function() {
- var element = digestMarkup($scope, $compile, markup);
- expect(element).toBeDefined();
-
- expect(element.children().length).toBe(1);
- expect(element.find('.progress-bar').hasClass('progress-bar-striped')).toBe(true);
- expect(element.find('.progress-bar').hasClass('progress-bar-danger')).toBe(false);
- expect(element.find('.progress-bar > span').length).toBe(1);
- expect(element.find('.progress-bar > span').hasClass('sr-only')).toBe(true);
- expect(element.find('.progress-bar > span').text().trim()).toBe('Loading');
- expect(element.find('.message').length).toBe(0);
- });
-
- it('indicates error status on error', function() {
- var element = digestMarkup($scope, $compile, markup);
- expect(element).toBeDefined();
-
- ctrl.loading = false;
- ctrl.error = true;
- $scope.$apply();
-
- expect(element.children().length).toBe(1);
- expect(element.find('.progress-bar').hasClass('progress-bar-striped')).toBe(false);
- expect(element.find('.progress-bar').hasClass('progress-bar-danger')).toBe(true);
- expect(element.find('.progress-bar > span').length).toBe(1);
- expect(element.find('.progress-bar > span').hasClass('sr-only')).toBe(false);
- expect(element.find('.progress-bar > span').text().trim())
- .toBe('An error occurred. Please try again later.');
- expect(element.find('.error-actions').length).toBe(1);
- expect(element.find('.error-actions > a').text().trim()).toBe('Back');
- });
-
- it('goes away when done loading', function() {
- var element = digestMarkup($scope, $compile, markup);
- expect(element).toBeDefined();
-
- ctrl.loading = false;
- ctrl.error = false;
- $scope.$apply();
-
- expect(element.children().length).toBe(0);
- });
-
- });
-}());
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/widgets/detail/detail-status.html b/octavia_dashboard/static/dashboard/project/lbaasv2/widgets/detail/detail-status.html
deleted file mode 100644
index 3278ed1a..00000000
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/widgets/detail/detail-status.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
- Loading
- An error occurred. Please try again later.
-
-
-
-
\ No newline at end of file
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/members/members.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/members/members.controller.spec.js
index 44e33a23..ae32b55c 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/members/members.controller.spec.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/members/members.controller.spec.js
@@ -17,9 +17,8 @@
'use strict';
describe('Member Details Step', function() {
- var model;
+ var model, ctrl;
- beforeEach(module('horizon.framework.util.i18n'));
beforeEach(module('horizon.dashboard.project.lbaasv2'));
beforeEach(function() {
@@ -47,128 +46,91 @@
};
});
- describe('MemberDetailsController', function() {
- var ctrl;
+ beforeEach(inject(function($controller, $rootScope) {
+ var scope = $rootScope.$new();
+ scope.model = model;
+ ctrl = $controller('MemberDetailsController', { $scope: scope });
+ $.fn.popover = angular.noop;
+ spyOn($.fn, 'popover');
+ }));
- beforeEach(inject(function($controller) {
- ctrl = $controller('MemberDetailsController', { $scope: { model: model } });
- }));
-
- it('should define error messages for invalid fields', function() {
- expect(ctrl.portError).toBeDefined();
- expect(ctrl.weightError).toBeDefined();
- expect(ctrl.ipError).toBeDefined();
- });
-
- it('should define patterns for validation', function() {
- expect(ctrl.ipPattern).toBeDefined();
- });
-
- it('should define transfer table properties', function() {
- expect(ctrl.tableData).toBeDefined();
- expect(ctrl.tableLimits).toBeDefined();
- expect(ctrl.tableHelp).toBeDefined();
- });
-
- it('should have available members', function() {
- expect(ctrl.tableData.available).toBeDefined();
- expect(ctrl.tableData.available.length).toBe(1);
- expect(ctrl.tableData.available[0].id).toBe('1');
- });
-
- it('should not have allocated members', function() {
- expect(ctrl.tableData.allocated).toEqual([]);
- });
-
- it('should allow adding multiple members', function() {
- expect(ctrl.tableLimits.maxAllocation).toBe(-1);
- });
-
- it('should properly format address popover target', function() {
- var target = ctrl.addressPopoverTarget(model.members[0]);
- expect(target).toBe('1.2.3.4...');
- });
-
- it('should allocate a new external member', function() {
- ctrl.allocateExternalMember();
- expect(model.spec.members.length).toBe(1);
- expect(model.spec.members[0].id).toBe(0);
- expect(model.spec.members[0].address).toBeNull();
- expect(model.spec.members[0].subnet).toBeNull();
- });
-
- it('should allocate a given member', function() {
- ctrl.allocateMember(model.members[0]);
- expect(model.spec.members.length).toBe(1);
- expect(model.spec.members[0].id).toBe(0);
- expect(model.spec.members[0].address).toEqual(model.members[0].address);
- expect(model.spec.members[0].subnet).toBeUndefined();
- expect(model.spec.members[0].port).toEqual(model.members[0].port);
- });
-
- it('should deallocate a given member', function() {
- ctrl.deallocateMember(model.spec.members[0]);
- expect(model.spec.members.length).toBe(0);
- });
-
- it('should show subnet name for available instance', function() {
- var name = ctrl.getSubnetName(model.members[0]);
- expect(name).toBe('subnet-1');
- });
+ it('should define error messages for invalid fields', function() {
+ expect(ctrl.portError).toBeDefined();
+ expect(ctrl.weightError).toBeDefined();
+ expect(ctrl.ipError).toBeDefined();
});
- describe('Member Details Step Template', function() {
- var $scope, $element, popoverContent;
+ it('should define patterns for validation', function() {
+ expect(ctrl.ipPattern).toBeDefined();
+ });
- beforeEach(module('templates'));
- beforeEach(module('horizon.dashboard.project.lbaasv2'));
+ it('should define transfer table properties', function() {
+ expect(ctrl.tableData).toBeDefined();
+ expect(ctrl.tableLimits).toBeDefined();
+ expect(ctrl.tableHelp).toBeDefined();
+ });
- beforeEach(inject(function($injector) {
- var $compile = $injector.get('$compile');
- var $templateCache = $injector.get('$templateCache');
- var basePath = $injector.get('horizon.dashboard.project.lbaasv2.basePath');
- var popoverTemplates = $injector.get('horizon.dashboard.project.lbaasv2.popovers');
- var markup = $templateCache.get(basePath + 'workflow/members/members.html');
- $scope = $injector.get('$rootScope').$new();
- $scope.model = model;
- $element = $compile(markup)($scope);
- var popoverScope = $injector.get('$rootScope').$new();
- popoverScope.member = model.members[0];
- popoverContent = $compile(popoverTemplates.ipAddresses)(popoverScope);
- }));
+ it('should have available members', function() {
+ expect(ctrl.tableData.available).toBeDefined();
+ expect(ctrl.tableData.available.length).toBe(1);
+ expect(ctrl.tableData.available[0].id).toBe('1');
+ });
- it('should show IP addresses popover on hover', function() {
- var ctrl = $element.scope().ctrl;
- ctrl.tableData.displayedAvailable = model.members;
- $scope.$apply();
+ it('should not have allocated members', function() {
+ expect(ctrl.tableData.allocated).toEqual([]);
+ });
- var popoverElement = $element.find('span.addresses-popover');
- expect(popoverElement.length).toBe(1);
+ it('should allow adding multiple members', function() {
+ expect(ctrl.tableLimits.maxAllocation).toBe(-1);
+ });
- $.fn.popover = angular.noop;
- spyOn($.fn, 'popover');
- spyOn(ctrl, 'showAddressPopover').and.callThrough();
- popoverElement.trigger('mouseover');
+ it('should properly format address popover target', function() {
+ var target = ctrl.addressPopoverTarget(model.members[0]);
+ expect(target).toBe('1.2.3.4...');
+ });
- expect(ctrl.showAddressPopover).toHaveBeenCalledWith(
- jasmine.objectContaining({type: 'mouseover'}), model.members[0]);
- expect($.fn.popover.calls.count()).toBe(2);
- expect($.fn.popover.calls.argsFor(0)[0]).toEqual({
- content: popoverContent,
- html: true,
- placement: 'top',
- title: 'IP Addresses (2)'
- });
- expect($.fn.popover.calls.argsFor(1)[0]).toBe('show');
+ it('should allocate a new external member', function() {
+ ctrl.allocateExternalMember();
+ expect(model.spec.members.length).toBe(1);
+ expect(model.spec.members[0].id).toBe(0);
+ expect(model.spec.members[0].address).toBeNull();
+ expect(model.spec.members[0].subnet).toBeNull();
+ });
- spyOn(ctrl, 'hideAddressPopover').and.callThrough();
- popoverElement.trigger('mouseleave');
+ it('should allocate a given member', function() {
+ ctrl.allocateMember(model.members[0]);
+ expect(model.spec.members.length).toBe(1);
+ expect(model.spec.members[0].id).toBe(0);
+ expect(model.spec.members[0].address).toEqual(model.members[0].address);
+ expect(model.spec.members[0].subnet).toBeUndefined();
+ expect(model.spec.members[0].port).toEqual(model.members[0].port);
+ });
- expect(ctrl.hideAddressPopover)
- .toHaveBeenCalledWith(jasmine.objectContaining({type: 'mouseleave'}));
- expect($.fn.popover.calls.count()).toBe(3);
- expect($.fn.popover.calls.argsFor(2)[0]).toBe('hide');
+ it('should deallocate a given member', function() {
+ ctrl.deallocateMember(model.spec.members[0]);
+ expect(model.spec.members.length).toBe(0);
+ });
+
+ it('should show subnet name for available instance', function() {
+ var name = ctrl.getSubnetName(model.members[0]);
+ expect(name).toBe('subnet-1');
+ });
+
+ it('should show IP addresses popover', function() {
+ ctrl.showAddressPopover({ target: 'foo' }, model.members[0]);
+ expect($.fn.popover.calls.count()).toBe(2);
+ expect($.fn.popover.calls.argsFor(0)[0]).toEqual({
+ content: jasmine.any(Object),
+ html: true,
+ placement: 'top',
+ title: 'IP Addresses (2)'
});
+ expect($.fn.popover.calls.argsFor(1)[0]).toBe('show');
+ });
+
+ it('should hide IP addresses popover', function() {
+ ctrl.hideAddressPopover({ target: 'foo' });
+ expect($.fn.popover).toHaveBeenCalledWith('hide');
});
});
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/modal.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/modal.service.js
index b8838d03..6ead2e02 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/modal.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/modal.service.js
@@ -64,6 +64,7 @@
function init(args) {
return {
+ handle: args.handle, // exposed just for testing
allowed: args.allowed,
perform: open
};
@@ -93,13 +94,13 @@
}
}
};
- $uibModal.open(spec).result.then(onModalClose);
+ return $uibModal.open(spec).result.then(onModalClose);
}
function onModalClose(response) {
toastService.add('success', args.message);
if (args.handle) {
- args.handle(response);
+ return args.handle(response);
}
}
}
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 87e7d2b4..191578a2 100644
--- a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.js
+++ b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.js
@@ -565,7 +565,7 @@
if (result.listener) {
model.visibleResources.push('listener');
- model.spec.loadbalancer_id = result.listener.loadbalancers[0].id;
+ model.spec.loadbalancer_id = result.listener.load_balancers[0].id;
if (result.listener.protocol === 'TERMINATED_HTTPS') {
keymanagerPromise.then(prepareCertificates).then(function addAvailableCertificates() {
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 64902e09..bab30f35 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
@@ -32,7 +32,7 @@
protocol: 'HTTP',
protocol_port: 80,
connection_limit: 999,
- loadbalancers: [ { id: '1234' } ],
+ load_balancers: [ { id: '1234' } ],
sni_container_refs: ['container2']
},
pool: {