Merge "Add details to network_qos panel"
This commit is contained in:
commit
0f1c10d6b3
@ -1616,3 +1616,11 @@ def policy_list(request, **kwargs):
|
||||
policies = neutronclient(request).list_qos_policies(
|
||||
**kwargs).get('policies')
|
||||
return [QoSPolicy(p) for p in policies]
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def policy_get(request, policy_id, **kwargs):
|
||||
"""Get QoS policy for a given policy id."""
|
||||
policy = neutronclient(request).show_qos_policy(
|
||||
policy_id, **kwargs).get('policy')
|
||||
return QoSPolicy(policy)
|
||||
|
@ -274,3 +274,15 @@ class QoSPolicies(generic.View):
|
||||
result = api.neutron.policy_list(request,
|
||||
project_id=request.user.project_id)
|
||||
return {'items': [p.to_dict() for p in result]}
|
||||
|
||||
|
||||
@urls.register
|
||||
class QoSPolicy(generic.View):
|
||||
"""API for a single QoS Policy."""
|
||||
url_regex = r'neutron/qos_policy/(?P<policy_id>[^/]+)/$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request, policy_id):
|
||||
"""Get a specific policy"""
|
||||
policy = api.neutron.policy_get(request, policy_id)
|
||||
return policy.to_dict()
|
||||
|
@ -15,8 +15,8 @@ from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon.browsers import views
|
||||
|
||||
title = _("Network QoS Policies")
|
||||
|
||||
title = _("Network QoS Policies")
|
||||
urlpatterns = [
|
||||
url(r'^$', views.AngularIndexView.as_view(title=title), name='index'),
|
||||
]
|
||||
|
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* 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.app.core.network_qos.details
|
||||
*
|
||||
* @description
|
||||
* Provides details features for policies.
|
||||
*/
|
||||
angular
|
||||
.module('horizon.app.core.network_qos.details', [
|
||||
'horizon.framework.conf',
|
||||
'horizon.app.core'
|
||||
])
|
||||
.run(registerPolicyDetails);
|
||||
|
||||
registerPolicyDetails.$inject = [
|
||||
'horizon.app.core.network_qos.basePath',
|
||||
'horizon.app.core.network_qos.resourceType',
|
||||
'horizon.app.core.network_qos.service',
|
||||
'horizon.framework.conf.resource-type-registry.service'
|
||||
];
|
||||
|
||||
function registerPolicyDetails(
|
||||
basePath,
|
||||
qosResourceType,
|
||||
qosService,
|
||||
registry
|
||||
) {
|
||||
registry.getResourceType(qosResourceType)
|
||||
.setLoadFunction(qosService.getPolicyPromise)
|
||||
.detailsViews.append({
|
||||
id: 'policyDetailsOverview',
|
||||
name: gettext('Overview'),
|
||||
template: basePath + 'details/overview.html'
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,19 @@
|
||||
<div>
|
||||
<hz-resource-property-list
|
||||
resource-type-name="OS::Neutron::QoSPolicy"
|
||||
item="item"
|
||||
property-groups="[
|
||||
['name', 'id'],
|
||||
['created_at','updated_at'],
|
||||
['project_id']]">
|
||||
</hz-resource-property-list>
|
||||
|
||||
<div class="row" ng-if="drawerCtrl.metadataDefs">
|
||||
<div class="col-sm-12">
|
||||
<metadata-display
|
||||
available="::drawerCtrl.metadataDefs"
|
||||
existing="item.properties || item">
|
||||
</metadata-display>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.app.core.network_qos')
|
||||
.controller('NetworkQoSOverviewController', NetworkQoSOverviewController);
|
||||
|
||||
NetworkQoSOverviewController.$inject = [
|
||||
'horizon.app.core.network_qos.resourceType',
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.app.core.openstack-service-api.userSession',
|
||||
'$scope'
|
||||
];
|
||||
|
||||
function NetworkQoSOverviewController(
|
||||
qosResourceTypeCode,
|
||||
registry,
|
||||
userSession,
|
||||
$scope
|
||||
) {
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.resourceType = registry.getResourceType(qosResourceTypeCode);
|
||||
ctrl.tableConfig = {
|
||||
selectAll: false,
|
||||
expand: false,
|
||||
trackId: 'id',
|
||||
/*
|
||||
* getTableColumns here won't work as that will give back the
|
||||
* columns for the policy, but here we need columns only for the
|
||||
* policy rules, which is a (list of) dictionary(ies) in the
|
||||
* policy dictionary.
|
||||
*/
|
||||
columns: [
|
||||
{id: 'id', title: gettext('Rule ID'), priority: 1, sortDefault: true},
|
||||
{id: 'type', title: gettext('Type'), priority: 1},
|
||||
{id: 'direction', title: gettext('Direction'), priority: 1},
|
||||
{id: 'max_kbps', title: gettext('Max Kbps'), priority: 1},
|
||||
{id: 'max_burst_kbps', title: gettext('Max Burst Kbits'), priority: 1},
|
||||
{id: 'min_kbps', title: gettext('Min Kbps'), priority: 1},
|
||||
{id: 'dscp_mark', title: gettext('DSCP Mark'), priority: 1}
|
||||
]
|
||||
};
|
||||
|
||||
$scope.context.loadPromise.then(onGetPolicy);
|
||||
|
||||
function onGetPolicy(response) {
|
||||
ctrl.policy = response.data;
|
||||
|
||||
userSession.get().then(setProject);
|
||||
|
||||
function setProject(session) {
|
||||
ctrl.projectId = session.project_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* 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('network qos overview controller', function() {
|
||||
var ctrl;
|
||||
var sessionObj = {project_id: '12'};
|
||||
var neutron = {
|
||||
getNamespaces: angular.noop
|
||||
};
|
||||
|
||||
beforeEach(module('horizon.app.core.network_qos'));
|
||||
beforeEach(module('horizon.framework.conf'));
|
||||
beforeEach(inject(function($controller, $q, $injector) {
|
||||
var session = $injector.get('horizon.app.core.openstack-service-api.userSession');
|
||||
var deferred = $q.defer();
|
||||
var sessionDeferred = $q.defer();
|
||||
deferred.resolve({data: {rules: [{'a': 'apple'}, [], {}]}});
|
||||
sessionDeferred.resolve(sessionObj);
|
||||
spyOn(neutron, 'getNamespaces').and.returnValue(deferred.promise);
|
||||
spyOn(session, 'get').and.returnValue(sessionDeferred.promise);
|
||||
ctrl = $controller('NetworkQoSOverviewController',
|
||||
{
|
||||
'$scope': {context: {loadPromise: deferred.promise}}
|
||||
}
|
||||
);
|
||||
}));
|
||||
|
||||
it('sets ctrl.resourceType', function() {
|
||||
expect(ctrl.resourceType).toBeDefined();
|
||||
});
|
||||
|
||||
it('sets ctrl.policy.rules (metadata)', inject(function($timeout) {
|
||||
$timeout.flush();
|
||||
expect(ctrl.policy).toBeDefined();
|
||||
expect(ctrl.policy.rules).toBeDefined();
|
||||
expect(ctrl.policy.rules[0]).toEqual({'a': 'apple'});
|
||||
}));
|
||||
|
||||
it('sets ctrl.policy.rules propValue if empty array', inject(function($timeout) {
|
||||
$timeout.flush();
|
||||
expect(ctrl.policy).toBeDefined();
|
||||
expect(ctrl.policy.rules).toBeDefined();
|
||||
expect(ctrl.policy.rules[1]).toEqual([]);
|
||||
}));
|
||||
|
||||
it('sets ctrl.policy.rules propValue if empty object', inject(function($timeout) {
|
||||
$timeout.flush();
|
||||
expect(ctrl.policy).toBeDefined();
|
||||
expect(ctrl.policy.rules).toBeDefined();
|
||||
expect(ctrl.policy.rules[2]).toEqual({});
|
||||
}));
|
||||
|
||||
it('sets ctrl.projectId', inject(function($timeout) {
|
||||
$timeout.flush();
|
||||
expect(ctrl.projectId).toBe(sessionObj.project_id);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
})();
|
@ -0,0 +1,37 @@
|
||||
<div ng-controller="NetworkQoSOverviewController as ctrl">
|
||||
<div class="row">
|
||||
<div class="col-md-6 detail">
|
||||
<h3 translate>Policy Details</h3>
|
||||
<hr>
|
||||
<hz-resource-property-list
|
||||
resource-type-name="OS::Neutron::QoSPolicy"
|
||||
cls="dl-horizontal"
|
||||
item="ctrl.policy"
|
||||
property-groups="[['name', 'description', 'id', 'project_id']]">
|
||||
</hz-resource-property-list>
|
||||
</div>
|
||||
<div class="col-md-6 detail">
|
||||
<h3 translate>Ownership</h3>
|
||||
<hr>
|
||||
<hz-resource-property-list
|
||||
resource-type-name="OS::Neutron::QoSPolicy"
|
||||
cls="dl-horizontal"
|
||||
item="ctrl.policy"
|
||||
property-groups="[['created_at', 'updated_at', 'shared', 'revision_number']]">
|
||||
</hz-resource-property-list>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12 detail">
|
||||
<h3 translate>Rules</h3>
|
||||
<hr>
|
||||
<dl class="dl-horizontal">
|
||||
<hz-dynamic-table
|
||||
config="ctrl.tableConfig"
|
||||
items="ctrl.policy.rules"
|
||||
table="ctrl">
|
||||
</hz-dynamic-table>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -25,7 +25,8 @@
|
||||
*/
|
||||
angular
|
||||
.module('horizon.app.core.network_qos', [
|
||||
'ngRoute'
|
||||
'ngRoute',
|
||||
'horizon.app.core.network_qos.details'
|
||||
])
|
||||
.constant('horizon.app.core.network_qos.resourceType', 'OS::Neutron::QoSPolicy')
|
||||
.run(run)
|
||||
@ -33,26 +34,26 @@
|
||||
|
||||
run.$inject = [
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.app.core.network_qos.basePath',
|
||||
'horizon.app.core.network_qos.service',
|
||||
'horizon.app.core.network_qos.resourceType'
|
||||
];
|
||||
|
||||
function run(registry,
|
||||
basePath,
|
||||
qosService,
|
||||
qosResourceType) {
|
||||
registry.getResourceType(qosResourceType)
|
||||
.setNames(gettext('QoS Policy'), gettext('QoS Policies'))
|
||||
.setSummaryTemplateUrl(basePath + 'details/drawer.html')
|
||||
.setProperties(qosProperties(qosService))
|
||||
.setListFunction(qosService.getPoliciesPromise)
|
||||
.tableColumns
|
||||
.append({
|
||||
id: 'name',
|
||||
priority: 1,
|
||||
sortDefault: true
|
||||
})
|
||||
.append({
|
||||
id: 'id',
|
||||
priority: 1
|
||||
sortDefault: true,
|
||||
urlFunction: qosService.getDetailsPath
|
||||
})
|
||||
.append({
|
||||
id: 'description',
|
||||
@ -70,11 +71,6 @@
|
||||
singleton: true,
|
||||
persistent: true
|
||||
})
|
||||
.append({
|
||||
label: gettext('Policy ID'),
|
||||
name: 'id',
|
||||
singleton: true
|
||||
})
|
||||
.append({
|
||||
label: gettext('Description'),
|
||||
name: 'description',
|
||||
@ -100,27 +96,46 @@
|
||||
name: gettext('Policy Name'),
|
||||
id: gettext('Policy ID'),
|
||||
description: gettext('Description'),
|
||||
shared: { label: gettext('Shared'), filters: ['yesno'] }
|
||||
shared: { label: gettext('Shared'), filters: ['yesno'] },
|
||||
tenant_id: gettext('Tenant ID'),
|
||||
project_id: gettext('Project ID'),
|
||||
created_at: gettext('Created At'),
|
||||
updated_at: gettext('Updated At'),
|
||||
rules: gettext('Rules'),
|
||||
revision_number: gettext('Revision Number')
|
||||
};
|
||||
}
|
||||
|
||||
config.$inject = [
|
||||
'$provide',
|
||||
'$windowProvider',
|
||||
'$routeProvider'
|
||||
'$routeProvider',
|
||||
'horizon.app.core.detailRoute'
|
||||
];
|
||||
|
||||
/**
|
||||
* @name horizon.dashboard.project.network_qos.basePath
|
||||
* @param {Object} $provide
|
||||
* @param {Object} $windowProvider
|
||||
* @param {Object} $routeProvider
|
||||
* @param {Object} detailRoute
|
||||
* @description Base path for the QoS code
|
||||
*/
|
||||
function config($provide, $windowProvider, $routeProvider) {
|
||||
function config($provide, $windowProvider, $routeProvider, detailRoute) {
|
||||
var path = $windowProvider.$get().STATIC_URL + 'app/core/network_qos/';
|
||||
$provide.constant('horizon.app.core.network_qos.basePath', path);
|
||||
|
||||
$routeProvider.when('/project/network_qos', {
|
||||
$routeProvider
|
||||
.when('/project/network_qos', {
|
||||
templateUrl: path + 'panel.html'
|
||||
})
|
||||
.when('/project/network_qos/:policy_id', {
|
||||
redirectTo: goToAngularDetails
|
||||
});
|
||||
|
||||
function goToAngularDetails(params) {
|
||||
return detailRoute + 'OS::Neutron::QoSPolicy/' + params.id;
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
|
@ -21,7 +21,8 @@
|
||||
qosService.$inject = [
|
||||
'$filter',
|
||||
'horizon.app.core.openstack-service-api.neutron',
|
||||
'horizon.app.core.openstack-service-api.userSession'
|
||||
'horizon.app.core.openstack-service-api.userSession',
|
||||
'horizon.app.core.detailRoute'
|
||||
];
|
||||
|
||||
/*
|
||||
@ -34,13 +35,30 @@
|
||||
* but do not need to be restricted to such use. Each exposed function
|
||||
* is documented below.
|
||||
*/
|
||||
function qosService($filter, neutron, userSession) {
|
||||
function qosService($filter,
|
||||
neutron,
|
||||
userSession,
|
||||
detailRoute) {
|
||||
var version;
|
||||
|
||||
return {
|
||||
getPoliciesPromise: getPoliciesPromise
|
||||
getDetailsPath: getDetailsPath,
|
||||
getPoliciesPromise: getPoliciesPromise,
|
||||
getPolicyPromise: getPolicyPromise
|
||||
};
|
||||
|
||||
/*
|
||||
* @ngdoc function
|
||||
* @name getDetailsPath
|
||||
* @param item {Object} - The QoS Policy object
|
||||
* @description
|
||||
* Given an QoS Policy object, returns the relative path to the details
|
||||
* view.
|
||||
*/
|
||||
function getDetailsPath(item) {
|
||||
return detailRoute + 'OS::Neutron::QoSPolicy/' + item.id;
|
||||
}
|
||||
|
||||
/*
|
||||
* @ngdoc function
|
||||
* @name getPoliciesPromise
|
||||
@ -69,6 +87,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @ngdoc function
|
||||
* @name getPolicyPromise
|
||||
* @description
|
||||
* Given an id, returns a promise for the policy data.
|
||||
*/
|
||||
function getPolicyPromise(identifier) {
|
||||
return neutron.getQosPolicy(identifier);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})();
|
||||
|
@ -51,6 +51,18 @@
|
||||
}));
|
||||
});
|
||||
|
||||
describe('getPolicyPromise', function() {
|
||||
it("provides a promise", inject(function($q, $injector) {
|
||||
var neutron = $injector.get('horizon.app.core.openstack-service-api.neutron');
|
||||
var deferred = $q.defer();
|
||||
spyOn(neutron, 'getQosPolicy').and.returnValue(deferred.promise);
|
||||
var result = service.getPolicyPromise({});
|
||||
deferred.resolve({data: {id: 1, name: 'policy1'}});
|
||||
expect(neutron.getQosPolicy).toHaveBeenCalled();
|
||||
expect(result.$$state.value.data.name).toBe('policy1');
|
||||
}));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})();
|
||||
|
@ -43,6 +43,7 @@
|
||||
getExtensions: getExtensions,
|
||||
getNetworks: getNetworks,
|
||||
getPorts: getPorts,
|
||||
getQosPolicy: getQosPolicy,
|
||||
getQoSPolicies: getQoSPolicies,
|
||||
getSubnets: getSubnets,
|
||||
getTrunks: getTrunks,
|
||||
@ -338,10 +339,23 @@
|
||||
|
||||
// QoS policies
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.neutron.getQosPolicy
|
||||
* @description get a single qos policy by ID.
|
||||
* @param {string} id
|
||||
* Specifies the id of the policy to request.
|
||||
* @returns {Object} The result of the API call
|
||||
*/
|
||||
function getQosPolicy(id) {
|
||||
return apiService.get('/api/neutron/qos_policy/' + id + '/')
|
||||
.error(function () {
|
||||
toastService.add('error', gettext('Unable to retrieve the qos policy.'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.neutron.getQoSPolicies
|
||||
* @description
|
||||
* Get a list of qos policies.
|
||||
* @description get a list of qos policies.
|
||||
*
|
||||
* The listing result is an object with property "items". Each item is
|
||||
* a QoS policy.
|
||||
|
@ -162,6 +162,15 @@
|
||||
42
|
||||
]
|
||||
},
|
||||
{
|
||||
"func": "getQosPolicy",
|
||||
"method": "get",
|
||||
"path": "/api/neutron/qos_policy/1/",
|
||||
"error": "Unable to retrieve the qos policy.",
|
||||
"testInput": [
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"func": "getQoSPolicies",
|
||||
"method": "get",
|
||||
|
Loading…
Reference in New Issue
Block a user