diff --git a/neutron_lbaas_dashboard/api/rest/lbaasv2.py b/neutron_lbaas_dashboard/api/rest/lbaasv2.py index fa319a1b..b2978306 100644 --- a/neutron_lbaas_dashboard/api/rest/lbaasv2.py +++ b/neutron_lbaas_dashboard/api/rest/lbaasv2.py @@ -346,3 +346,19 @@ class Member(generic.View): """ lb = neutronclient(request).show_lbaas_member(member_id, pool_id) return lb.get('member') + + +@urls.register +class HealthMonitor(generic.View): + """API for retrieving a single health monitor. + + """ + url_regex = r'lbaas/healthmonitors/(?P[^/]+)/$' + + @rest_utils.ajax() + def get(self, request, healthmonitor_id): + """Get a specific health monitor. + + """ + lb = neutronclient(request).show_lbaas_healthmonitor(healthmonitor_id) + return lb.get('healthmonitor') diff --git a/neutron_lbaas_dashboard/enabled/_1481_project_ng_loadbalancersv2_panel.py b/neutron_lbaas_dashboard/enabled/_1481_project_ng_loadbalancersv2_panel.py index 9a6e6e8c..5d082335 100644 --- a/neutron_lbaas_dashboard/enabled/_1481_project_ng_loadbalancersv2_panel.py +++ b/neutron_lbaas_dashboard/enabled/_1481_project_ng_loadbalancersv2_panel.py @@ -60,7 +60,9 @@ ADD_JS_FILES = [ 'dashboard/project/lbaasv2/pools/detail.controller.js', 'dashboard/project/lbaasv2/members/members.module.js', 'dashboard/project/lbaasv2/members/detail.controller.js', - 'dashboard/project/lbaasv2/members/table.controller.js' + 'dashboard/project/lbaasv2/members/table.controller.js', + 'dashboard/project/lbaasv2/healthmonitors/healthmonitors.module.js', + 'dashboard/project/lbaasv2/healthmonitors/detail.controller.js' ] ADD_JS_SPEC_FILES = [ @@ -95,7 +97,9 @@ ADD_JS_SPEC_FILES = [ 'dashboard/project/lbaasv2/pools/detail.controller.spec.js', 'dashboard/project/lbaasv2/members/members.module.spec.js', 'dashboard/project/lbaasv2/members/detail.controller.spec.js', - 'dashboard/project/lbaasv2/members/table.controller.spec.js' + 'dashboard/project/lbaasv2/members/table.controller.spec.js', + 'dashboard/project/lbaasv2/healthmonitors/healthmonitors.module.spec.js', + 'dashboard/project/lbaasv2/healthmonitors/detail.controller.spec.js' ] ADD_SCSS_FILES = [ diff --git a/neutron_lbaas_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js b/neutron_lbaas_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js index 5cc25cc8..3c05e07d 100644 --- a/neutron_lbaas_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js +++ b/neutron_lbaas_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js @@ -44,7 +44,8 @@ getListener: getListener, getPool: getPool, getMembers: getMembers, - getMember: getMember + getMember: getMember, + getHealthMonitor: getHealthMonitor }; return service; @@ -208,5 +209,20 @@ }); } + /** + * @name horizon.app.core.openstack-service-api.lbaasv2.getHealthMonitor + * @description + * Get a single pool health monitor by ID. + * @param {string} monitorId + * Specifies the id of the health monitor. + */ + + function getHealthMonitor(monitorId) { + return apiService.get('/api/lbaas/healthmonitors/' + monitorId) + .error(function () { + toastService.add('error', gettext('Unable to retrieve health monitor.')); + }); + } + } }()); diff --git a/neutron_lbaas_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js b/neutron_lbaas_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js index 5d793f02..70fdb157 100644 --- a/neutron_lbaas_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js +++ b/neutron_lbaas_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js @@ -109,6 +109,15 @@ '5678' ] }, + { + "func": "getHealthMonitor", + "method": "get", + "path": "/api/lbaas/healthmonitors/1234", + "error": "Unable to retrieve health monitor.", + "testInput": [ + '1234' + ] + }, { "func": "createLoadBalancer", "method": "post", diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.controller.js b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.controller.js new file mode 100644 index 00000000..1ff2f355 --- /dev/null +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.controller.js @@ -0,0 +1,102 @@ +/* + * 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', + '$routeParams' + ]; + + /** + * @ngdoc controller + * @name HealthMonitorDetailController + * + * @description + * Controller for the LBaaS v2 health monitor detail page. + * + * @param api The LBaaS v2 API service. + * @param $routeParams The angular $routeParams service. + * @returns undefined + */ + + function HealthMonitorDetailController(api, $routeParams) { + var ctrl = this; + ctrl.healthmonitor = {}; + ctrl.pool = {}; + ctrl.listener = {}; + ctrl.loadbalancer = {}; + + var healthmonitorID = $routeParams.healthmonitorId; + + init(); + + //////////////////////////////// + + function init() { + api.getHealthMonitor(healthmonitorID).success(healthMonitorSuccess); + } + + function healthMonitorSuccess(response) { + ctrl.healthmonitor = response; + + if (ctrl.healthmonitor.hasOwnProperty('pools') && + ctrl.healthmonitor.pools.length > 0) { + getPoolDetails(ctrl.healthmonitor.pools[0].id); + } + } + + function getPoolDetails(poolId) { + api.getPool(poolId).success(poolSuccess); + } + + function poolSuccess(response) { + ctrl.pool = response; + + if (ctrl.pool.hasOwnProperty('listeners') && + ctrl.pool.listeners.length > 0) { + getListenerDetails(ctrl.pool.listeners[0].id); + } + } + + function getListenerDetails(listenerId) { + api.getListener(listenerId).success(listenerSuccess); + } + + function listenerSuccess(response) { + ctrl.listener = response; + + if (ctrl.listener.hasOwnProperty('loadbalancers') && + ctrl.listener.loadbalancers.length > 0) { + getLoadBalancerDetails(ctrl.listener.loadbalancers[0].id); + } + } + + function getLoadBalancerDetails(loadbalancerId) { + api.getLoadBalancer(loadbalancerId).success(loadbalancerSuccess); + } + + function loadbalancerSuccess(response) { + ctrl.loadbalancer = response; + } + + } + +})(); diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.controller.spec.js b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.controller.spec.js new file mode 100644 index 00000000..a3345e48 --- /dev/null +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.controller.spec.js @@ -0,0 +1,122 @@ +/* + * 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 controller, lbaasv2API, healthmonitor, pool, listener, loadbalancer; + + function fakeHealthMonitorAPI() { + return { + success: function(callback) { + callback(healthmonitor); + } + }; + } + + function fakePoolAPI() { + return { + success: function(callback) { + callback(pool); + } + }; + } + + function fakeListenerAPI() { + return { + success: function(callback) { + callback(listener); + } + }; + } + + function fakeLoadBalancerAPI() { + return { + success: function(callback) { + callback(loadbalancer); + } + }; + } + + /////////////////////// + + beforeEach(module('horizon.framework.util.http')); + beforeEach(module('horizon.framework.widgets.toast')); + beforeEach(module('horizon.framework.conf')); + beforeEach(module('horizon.app.core.openstack-service-api')); + beforeEach(module('horizon.dashboard.project.lbaasv2')); + + beforeEach(inject(function($injector) { + lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2'); + controller = $injector.get('$controller'); + spyOn(lbaasv2API, 'getHealthMonitor').and.callFake(fakeHealthMonitorAPI); + spyOn(lbaasv2API, 'getPool').and.callFake(fakePoolAPI); + spyOn(lbaasv2API, 'getListener').and.callFake(fakeListenerAPI); + spyOn(lbaasv2API, 'getLoadBalancer').and.callFake(fakeLoadBalancerAPI); + })); + + function createController() { + return controller('HealthMonitorDetailController', { + api: lbaasv2API, + $routeParams: { healthmonitorId: 'healthmonitorId' } + }); + } + + it('should invoke lbaasv2 apis', function() { + healthmonitor = { id: 'healthmonitorId', pools: [{id: 'poolId'}] }; + pool = { id: 'poolId', listeners: [{id: 'listenerId'}] }; + listener = { id: 'listenerId', loadbalancers: [{id: 'loadbalancerId'}] }; + loadbalancer = { id: 'loadbalancerId' }; + createController(); + expect(lbaasv2API.getHealthMonitor).toHaveBeenCalledWith('healthmonitorId'); + expect(lbaasv2API.getPool).toHaveBeenCalledWith('poolId'); + expect(lbaasv2API.getListener).toHaveBeenCalledWith('listenerId'); + expect(lbaasv2API.getLoadBalancer).toHaveBeenCalledWith('loadbalancerId'); + }); + + it('should not invoke the getPool, getListener or getLoadBalancer lbaasv2 api', function() { + healthmonitor = { id: 'healthmonitorId', pools: [] }; + createController(); + expect(lbaasv2API.getHealthMonitor).toHaveBeenCalledWith('healthmonitorId'); + expect(lbaasv2API.getPool).not.toHaveBeenCalled(); + expect(lbaasv2API.getListener).not.toHaveBeenCalled(); + expect(lbaasv2API.getLoadBalancer).not.toHaveBeenCalled(); + }); + + it('should not invoke the getListener or getLoadBalancer lbaasv2 api', function() { + healthmonitor = { id: 'healthmonitorId', pools: [{id: 'poolId'}] }; + pool = { id: 'poolId', listeners: [] }; + createController(); + expect(lbaasv2API.getHealthMonitor).toHaveBeenCalledWith('healthmonitorId'); + expect(lbaasv2API.getPool).toHaveBeenCalledWith('poolId'); + expect(lbaasv2API.getListener).not.toHaveBeenCalled(); + expect(lbaasv2API.getLoadBalancer).not.toHaveBeenCalled(); + }); + + it('should not invoke getLoadBalancer lbaasv2 api', function() { + healthmonitor = { id: 'healthmonitorId', pools: [{id: 'poolId'}] }; + pool = { id: 'poolId', listeners: [{id: 'listenerId'}] }; + listener = { id: 'listenerId', loadbalancers: [] }; + createController(); + expect(lbaasv2API.getHealthMonitor).toHaveBeenCalledWith('healthmonitorId'); + expect(lbaasv2API.getPool).toHaveBeenCalledWith('poolId'); + expect(lbaasv2API.getListener).toHaveBeenCalledWith('listenerId'); + expect(lbaasv2API.getLoadBalancer).not.toHaveBeenCalled(); + }); + + }); + +})(); diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.html b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.html new file mode 100644 index 00000000..ed2d6630 --- /dev/null +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.html @@ -0,0 +1,55 @@ +
+ +
+
+
+
Monitor ID
+
{$ ::ctrl.healthmonitor.id $}
+
+
+
Tenant ID
+
{$ ::ctrl.healthmonitor.tenant_id $}
+
+
+
Type
+
{$ ::ctrl.healthmonitor.type $}
+
+
+
HTTP Method
+
{$ ::ctrl.healthmonitor.http_method $}
+
+
+
Admin State Up
+
{$ ::ctrl.healthmonitor.admin_state | yesno $}
+
+
+
Expected Codes
+
{$ ::ctrl.healthmonitor.expected_codes $}
+
+
+
Max Retries
+
{$ ::ctrl.healthmonitor.max_retries $}
+
+
+
Timeout
+
{$ ::ctrl.healthmonitor.timeout $}
+
+
+
Delay
+
{$ ::ctrl.healthmonitor.delay $}
+
+
+
URL Path
+
{$ ::ctrl.healthmonitor.url_path $}
+
+
+
+
\ No newline at end of file diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/healthmonitors/healthmonitors.module.js b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/healthmonitors/healthmonitors.module.js new file mode 100644 index 00000000..0a7d50fc --- /dev/null +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/healthmonitors/healthmonitors.module.js @@ -0,0 +1,31 @@ +/* + * Copyright 2016 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +(function() { + 'use strict'; + + /** + * @ngdoc overview + * @ngname horizon.dashboard.project.lbaasv2.healthmonitors + * + * @description + * Provides the services and widgets required to support and display the project healthmonitors + * for the load balancers v2 panel. + */ + + angular + .module('horizon.dashboard.project.lbaasv2.healthmonitors', []); + +})(); diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/healthmonitors/healthmonitors.module.spec.js b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/healthmonitors/healthmonitors.module.spec.js new file mode 100644 index 00000000..63198d6a --- /dev/null +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/healthmonitors/healthmonitors.module.spec.js @@ -0,0 +1,25 @@ +/* + * Copyright 2016 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +(function() { + 'use strict'; + + describe('LBaaS v2 Healthmonitors Module', function() { + it('should exist', function() { + expect(angular.module('horizon.dashboard.project.lbaasv2.healthmonitors')).toBeDefined(); + }); + }); + +})(); diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js index 250ffbc5..70afc150 100644 --- a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js @@ -29,7 +29,8 @@ 'horizon.dashboard.project.lbaasv2.loadbalancers', 'horizon.dashboard.project.lbaasv2.listeners', 'horizon.dashboard.project.lbaasv2.pools', - 'horizon.dashboard.project.lbaasv2.members' + 'horizon.dashboard.project.lbaasv2.members', + 'horizon.dashboard.project.lbaasv2.healthmonitors' ]) .config(config) .constant('horizon.dashboard.project.lbaasv2.patterns', { @@ -72,6 +73,9 @@ }) .when(href + 'pools/:poolId/members/detail/:memberId', { templateUrl: basePath + 'members/detail.html' + }) + .when(href + 'healthmonitors/detail/:healthmonitorId', { + templateUrl: basePath + 'healthmonitors/detail.html' }); } diff --git a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js index 0d706ebc..62e08a26 100644 --- a/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js +++ b/neutron_lbaas_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js @@ -126,10 +126,16 @@ { templateUrl: basePath + 'members/detail.html' } + ], + [ + href + 'healthmonitors/detail/:healthmonitorId', + { + templateUrl: basePath + 'healthmonitors/detail.html' + } ] ]; - expect($routeProvider.when.calls.count()).toBe(5); + expect($routeProvider.when.calls.count()).toBe(6); angular.forEach($routeProvider.when.calls.all(), function(call, i) { expect(call.args).toEqual(routes[i]); });