Adds basic angular QoS panel to Horizon
This patch adds the QoS panel which displays Neutron QoS policies. This patch allows read only view of the policies, displaying the name, id, description and shared status of each policy. Policy actions and rules to be added in follow-up patches. To test: Neutron's QoS plugin must be enabled in your setup. To enable the QoS plugin in devstack please add the following lines in the local.conf enable_plugin neutron git://git.openstack.org/openstack/neutron enable_service q-qos and rebuild your stack (./stack.sh). Create some qos policies via CLI (neutron qos-policy-create policy1). now you can list the policies using this patch. Based on initial commit: https://review.openstack.org/#/c/247997 Co-Authored-By: Masco <mkaliyam@redhat.com> Co-Authored-By: Rob Cresswell <robert.cresswell@outlook.com> Change-Id: If46aeb04879d91a1a9305a94a23cecea2041d378 Implements: blueprint network-bandwidth-limiting-qos
This commit is contained in:
parent
bfaa4e64ec
commit
12fe351823
openstack_dashboard
api
dashboards/project/network_qos
enabled
static/app/core
test
releasenotes/notes
@ -1570,3 +1570,31 @@ def get_feature_permission(request, feature, operation=None):
|
||||
|
||||
# If all checks are passed, now a given feature is allowed.
|
||||
return True
|
||||
|
||||
|
||||
class QoSPolicy(NeutronAPIDictWrapper):
|
||||
"""Wrapper for neutron QoS Policy."""
|
||||
|
||||
def to_dict(self):
|
||||
return self._apidict
|
||||
|
||||
|
||||
def policy_create(request, **kwargs):
|
||||
"""Create a QoS Policy.
|
||||
|
||||
:param request: request context
|
||||
:param name: name of the policy
|
||||
:param description: description of policy
|
||||
:param shared: boolean (true or false)
|
||||
:return: QoSPolicy object
|
||||
"""
|
||||
body = {'policy': kwargs}
|
||||
policy = neutronclient(request).create_qos_policy(body=body).get('policy')
|
||||
return QoSPolicy(policy)
|
||||
|
||||
|
||||
def policy_list(request, **kwargs):
|
||||
"""List of QoS Policies."""
|
||||
policies = neutronclient(request).list_qos_policies(
|
||||
**kwargs).get('policies')
|
||||
return [QoSPolicy(p) for p in policies]
|
||||
|
@ -243,3 +243,24 @@ class QuotasSets(generic.View):
|
||||
message = _('Service Neutron is disabled or quotas extension not '
|
||||
'available.')
|
||||
raise rest_utils.AjaxError(501, message)
|
||||
|
||||
|
||||
@urls.register
|
||||
class QoSPolicies(generic.View):
|
||||
"""API for QoS Policy."""
|
||||
url_regex = r'neutron/qos_policies/$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request):
|
||||
"""Get a list of QoS policies.
|
||||
|
||||
The listing result is an object with property "items".
|
||||
Each item is a qos policy.
|
||||
"""
|
||||
# TODO(amotoki):
|
||||
# project_id=request.user.project_id should be changed to
|
||||
# tenant_id=request.user.project_id once bug 1695954 is
|
||||
# addressed to allow tenant_id to be accepted.
|
||||
result = api.neutron.policy_list(request,
|
||||
project_id=request.user.project_id)
|
||||
return {'items': [p.to_dict() for p in result]}
|
||||
|
42
openstack_dashboard/dashboards/project/network_qos/panel.py
Normal file
42
openstack_dashboard/dashboards/project/network_qos/panel.py
Normal file
@ -0,0 +1,42 @@
|
||||
# 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.
|
||||
|
||||
import logging
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
import horizon
|
||||
|
||||
from openstack_dashboard.api import neutron
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NetworkQoS(horizon.Panel):
|
||||
name = _("Network QoS")
|
||||
slug = "network_qos"
|
||||
permissions = ('openstack.services.network',)
|
||||
|
||||
def allowed(self, context):
|
||||
request = context['request']
|
||||
try:
|
||||
return (
|
||||
super(NetworkQoS, self).allowed(context)
|
||||
and request.user.has_perms(self.permissions)
|
||||
and neutron.is_extension_supported(request,
|
||||
extension_alias='qos')
|
||||
)
|
||||
except Exception:
|
||||
LOG.error("Call to list enabled services failed. This is likely "
|
||||
"due to a problem communicating with the Neutron "
|
||||
"endpoint. Neutron QoS panel will not be displayed.")
|
||||
return False
|
22
openstack_dashboard/dashboards/project/network_qos/urls.py
Normal file
22
openstack_dashboard/dashboards/project/network_qos/urls.py
Normal file
@ -0,0 +1,22 @@
|
||||
# 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.
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon.browsers import views
|
||||
|
||||
title = _("Network QoS Policies")
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.AngularIndexView.as_view(title=title), name='index'),
|
||||
]
|
@ -0,0 +1,10 @@
|
||||
# The slug of the panel to be added to HORIZON_CONFIG. Required.
|
||||
PANEL = 'network_qos'
|
||||
# The slug of the dashboard the PANEL associated with. Required.
|
||||
PANEL_DASHBOARD = 'project'
|
||||
# The slug of the panel group the PANEL is associated with.
|
||||
PANEL_GROUP = 'network'
|
||||
|
||||
# Python panel class of the PANEL to be added.
|
||||
ADD_PANEL = ('openstack_dashboard.dashboards.project.network_qos'
|
||||
'.panel.NetworkQoS')
|
@ -37,6 +37,7 @@
|
||||
'horizon.app.core.flavors',
|
||||
'horizon.app.core.images',
|
||||
'horizon.app.core.metadata',
|
||||
'horizon.app.core.network_qos',
|
||||
'horizon.app.core.openstack-service-api',
|
||||
'horizon.app.core.trunks',
|
||||
'horizon.app.core.workflow',
|
||||
|
@ -0,0 +1,3 @@
|
||||
<hz-resource-panel resource-type-name="OS::Neutron::QoSPolicy">
|
||||
<hz-resource-table resource-type-name="OS::Neutron::QoSPolicy"></hz-resource-table>
|
||||
</hz-resource-panel>
|
127
openstack_dashboard/static/app/core/network_qos/qos.module.js
Normal file
127
openstack_dashboard/static/app/core/network_qos/qos.module.js
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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 horizon.dashboard.project.network_qos
|
||||
* @ngModule
|
||||
*
|
||||
* @description
|
||||
* Provides all of the services and widgets required
|
||||
* to support and display the QoS panel.
|
||||
*/
|
||||
angular
|
||||
.module('horizon.app.core.network_qos', [
|
||||
'ngRoute'
|
||||
])
|
||||
.constant('horizon.app.core.network_qos.resourceType', 'OS::Neutron::QoSPolicy')
|
||||
.run(run)
|
||||
.config(config);
|
||||
|
||||
run.$inject = [
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.app.core.network_qos.service',
|
||||
'horizon.app.core.network_qos.resourceType',
|
||||
'horizon.app.core.openstack-service-api.neutron'
|
||||
];
|
||||
|
||||
function run(registry,
|
||||
qosService,
|
||||
qosResourceType) {
|
||||
registry.getResourceType(qosResourceType)
|
||||
.setNames(gettext('QoS Policy'), gettext('QoS Policies'))
|
||||
.setProperties(qosProperties(qosService))
|
||||
.setListFunction(qosService.getPoliciesPromise)
|
||||
.tableColumns
|
||||
.append({
|
||||
id: 'name',
|
||||
priority: 1,
|
||||
sortDefault: true
|
||||
})
|
||||
.append({
|
||||
id: 'id',
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'description',
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'shared',
|
||||
priority: 1
|
||||
});
|
||||
|
||||
registry.getResourceType(qosResourceType).filterFacets
|
||||
.append({
|
||||
label: gettext('Policy Name'),
|
||||
name: 'name',
|
||||
singleton: true,
|
||||
persistent: true
|
||||
})
|
||||
.append({
|
||||
label: gettext('Policy ID'),
|
||||
name: 'id',
|
||||
singleton: true
|
||||
})
|
||||
.append({
|
||||
label: gettext('Description'),
|
||||
name: 'description',
|
||||
singleton: true
|
||||
})
|
||||
.append({
|
||||
label: gettext('Shared'),
|
||||
name: 'shared',
|
||||
singleton: true,
|
||||
options: [
|
||||
{label: gettext('Yes'), key: 'true'},
|
||||
{label: gettext('No'), key: 'false'}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @name qosProperties
|
||||
* @description resource properties for QoS module
|
||||
*/
|
||||
function qosProperties() {
|
||||
return {
|
||||
name: gettext('Policy Name'),
|
||||
id: gettext('Policy ID'),
|
||||
description: gettext('Description'),
|
||||
shared: { label: gettext('Shared'), filters: ['yesno'] }
|
||||
};
|
||||
}
|
||||
|
||||
config.$inject = [
|
||||
'$provide',
|
||||
'$windowProvider',
|
||||
'$routeProvider'
|
||||
];
|
||||
|
||||
/**
|
||||
* @name horizon.dashboard.project.network_qos.basePath
|
||||
* @description Base path for the QoS code
|
||||
*/
|
||||
function config($provide, $windowProvider, $routeProvider) {
|
||||
var path = $windowProvider.$get().STATIC_URL + 'app/core/network_qos/';
|
||||
$provide.constant('horizon.app.core.network_qos.basePath', path);
|
||||
|
||||
$routeProvider.when('/project/network_qos', {
|
||||
templateUrl: path + 'panel.html'
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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('horizon.app.core.network_qos', function () {
|
||||
it('should exist', function () {
|
||||
expect(angular.module('horizon.app.core.network_qos')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
@ -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";
|
||||
|
||||
angular.module('horizon.app.core.network_qos')
|
||||
.factory('horizon.app.core.network_qos.service', qosService);
|
||||
|
||||
qosService.$inject = [
|
||||
'$filter',
|
||||
'horizon.app.core.openstack-service-api.neutron',
|
||||
'horizon.app.core.openstack-service-api.userSession'
|
||||
];
|
||||
|
||||
/*
|
||||
* @ngdoc factory
|
||||
* @name horizon.app.core.network_qos.service
|
||||
*
|
||||
* @description
|
||||
* This service provides functions that are used through the QoS
|
||||
* features. These are primarily used in the module registrations
|
||||
* but do not need to be restricted to such use. Each exposed function
|
||||
* is documented below.
|
||||
*/
|
||||
function qosService($filter, neutron, userSession) {
|
||||
var version;
|
||||
|
||||
return {
|
||||
getPoliciesPromise: getPoliciesPromise
|
||||
};
|
||||
|
||||
/*
|
||||
* @ngdoc function
|
||||
* @name getPoliciesPromise
|
||||
* @description
|
||||
* Given filter/query parameters, returns a promise for the matching
|
||||
* policies. This is used in displaying lists of policies. In this case,
|
||||
* we need to modify the API's response by adding a composite value called
|
||||
* 'trackBy' to assist the display mechanism when updating rows.
|
||||
*/
|
||||
function getPoliciesPromise(params) {
|
||||
return userSession.get().then(getQoSPolicies);
|
||||
|
||||
function getQoSPolicies() {
|
||||
return neutron.getQoSPolicies(params).then(modifyResponse);
|
||||
}
|
||||
|
||||
function modifyResponse(response) {
|
||||
return {data: {items: response.data.items.map(modifyQos)}};
|
||||
|
||||
function modifyQos(policy) {
|
||||
policy.trackBy = policy.id;
|
||||
policy.apiVersion = version;
|
||||
policy.name = policy.name || policy.id;
|
||||
return policy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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('horizon.app.core.network_qos', function () {
|
||||
it('should exist', function () {
|
||||
expect(angular.module('horizon.app.core.network_qos')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('qosService', function() {
|
||||
var service;
|
||||
beforeEach(module('horizon.app.core'));
|
||||
beforeEach(inject(function($injector) {
|
||||
service = $injector.get('horizon.app.core.network_qos.service');
|
||||
}));
|
||||
|
||||
describe('getPoliciesPromise', function() {
|
||||
it("provides a promise that gets translated", inject(function($q, $injector, $timeout) {
|
||||
var neutron = $injector.get('horizon.app.core.openstack-service-api.neutron');
|
||||
var session = $injector.get('horizon.app.core.openstack-service-api.userSession');
|
||||
var deferred = $q.defer();
|
||||
var deferredSession = $q.defer();
|
||||
spyOn(neutron, 'getQoSPolicies').and.returnValue(deferred.promise);
|
||||
spyOn(session, 'get').and.returnValue(deferredSession.promise);
|
||||
var result = service.getPoliciesPromise({});
|
||||
deferredSession.resolve({});
|
||||
deferred.resolve({
|
||||
data: {
|
||||
items: [{id: 1, name: 'policy1'},{id:2}]
|
||||
}
|
||||
});
|
||||
$timeout.flush();
|
||||
expect(neutron.getQoSPolicies).toHaveBeenCalled();
|
||||
expect(result.$$state.value.data.items[0].name).toBe('policy1');
|
||||
expect(result.$$state.value.data.items[0].trackBy).toBe(1);
|
||||
//if no name given, name should be id value
|
||||
expect(result.$$state.value.data.items[1].name).toBe(2);
|
||||
}));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})();
|
@ -44,7 +44,8 @@
|
||||
getExtensions: getExtensions,
|
||||
getDefaultQuotaSets: getDefaultQuotaSets,
|
||||
updateProjectQuota: updateProjectQuota,
|
||||
getTrunks: getTrunks
|
||||
getTrunks: getTrunks,
|
||||
getQoSPolicies: getQoSPolicies
|
||||
};
|
||||
|
||||
return service;
|
||||
@ -334,6 +335,23 @@
|
||||
});
|
||||
}
|
||||
|
||||
// QoS policies
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.neutron.getQoSPolicies
|
||||
* @description
|
||||
* Get a list of qos policies.
|
||||
*
|
||||
* The listing result is an object with property "items". Each item is
|
||||
* a QoS policy.
|
||||
*/
|
||||
function getQoSPolicies() {
|
||||
return apiService.get('/api/neutron/qos_policies/')
|
||||
.error(function () {
|
||||
toastService.add('error', gettext('Unable to retrieve the qos policies.'));
|
||||
});
|
||||
}
|
||||
|
||||
// Trunks
|
||||
|
||||
/**
|
||||
|
@ -22,18 +22,17 @@
|
||||
var apiService = {};
|
||||
var toastService = {};
|
||||
|
||||
beforeEach(
|
||||
module('horizon.mock.openstack-service-api',
|
||||
function($provide, initServices) {
|
||||
testCall = initServices($provide, apiService, toastService);
|
||||
})
|
||||
);
|
||||
beforeEach(function() {
|
||||
module('horizon.mock.openstack-service-api', function($provide, initServices) {
|
||||
testCall = initServices($provide, apiService, toastService);
|
||||
});
|
||||
|
||||
beforeEach(module('horizon.app.core.openstack-service-api'));
|
||||
module('horizon.app.core.openstack-service-api');
|
||||
|
||||
beforeEach(inject(['horizon.app.core.openstack-service-api.neutron', function(neutronAPI) {
|
||||
service = neutronAPI;
|
||||
}]));
|
||||
inject(['horizon.app.core.openstack-service-api.neutron', function(neutronAPI) {
|
||||
service = neutronAPI;
|
||||
}]);
|
||||
});
|
||||
|
||||
it('defines the service', function() {
|
||||
expect(service).toBeDefined();
|
||||
@ -149,6 +148,12 @@
|
||||
"testInput": [
|
||||
42
|
||||
]
|
||||
},
|
||||
{
|
||||
"func": "getQoSPolicies",
|
||||
"method": "get",
|
||||
"path": "/api/neutron/qos_policies/",
|
||||
"error": "Unable to retrieve the qos policies."
|
||||
}
|
||||
];
|
||||
|
||||
@ -161,4 +166,5 @@
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})();
|
||||
|
@ -702,6 +702,33 @@ class NeutronApiTests(test.APITestCase):
|
||||
self.assertEqual(10, len(ret_val))
|
||||
self.assertEqual(port_ids, [p.id for p in ret_val])
|
||||
|
||||
def test_qos_policies_list(self):
|
||||
exp_policies = self.qos_policies.list()
|
||||
api_qos_policies = {'policies': self.api_qos_policies.list()}
|
||||
|
||||
neutronclient = self.stub_neutronclient()
|
||||
neutronclient.list_qos_policies().AndReturn(api_qos_policies)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
ret_val = api.neutron.policy_list(self.request)
|
||||
self.assertEqual(len(ret_val), len(exp_policies))
|
||||
self.assertIsInstance(ret_val[0], api.neutron.QoSPolicy)
|
||||
self.assertEqual(exp_policies[0].name, ret_val[0].name)
|
||||
|
||||
def test_qos_policy_create(self):
|
||||
qos_policy = self.api_qos_policies.first()
|
||||
post_data = {'policy': {'name': qos_policy['name']}}
|
||||
|
||||
neutronclient = self.stub_neutronclient()
|
||||
neutronclient.create_qos_policy(body=post_data) \
|
||||
.AndReturn({'policy': qos_policy})
|
||||
self.mox.ReplayAll()
|
||||
|
||||
ret_val = api.neutron.policy_create(self.request,
|
||||
name=qos_policy['name'])
|
||||
self.assertIsInstance(ret_val, api.neutron.QoSPolicy)
|
||||
self.assertEqual(qos_policy['name'], ret_val.name)
|
||||
|
||||
|
||||
class NeutronApiSecurityGroupTests(NeutronApiTestBase):
|
||||
|
||||
|
@ -290,6 +290,11 @@ TEST_GLOBAL_MOCKS_ON_PANELS = {
|
||||
'.trunks.panel.Trunks.can_access'),
|
||||
'return_value': True,
|
||||
},
|
||||
'qos': {
|
||||
'method': ('openstack_dashboard.dashboards.project'
|
||||
'.network_qos.panel.NetworkQoS.can_access'),
|
||||
'return_value': True,
|
||||
},
|
||||
'vpn': {
|
||||
'method': ('openstack_dashboard.dashboards.project'
|
||||
'.vpn.panel.VPN.can_access'),
|
||||
|
@ -53,6 +53,7 @@ def data(TEST):
|
||||
TEST.fw_policies = utils.TestDataContainer()
|
||||
TEST.fw_rules = utils.TestDataContainer()
|
||||
TEST.ip_availability = utils.TestDataContainer()
|
||||
TEST.qos_policies = utils.TestDataContainer()
|
||||
|
||||
# Data return by neutronclient.
|
||||
TEST.api_agents = utils.TestDataContainer()
|
||||
@ -79,6 +80,7 @@ def data(TEST):
|
||||
TEST.api_fw_policies = utils.TestDataContainer()
|
||||
TEST.api_fw_rules = utils.TestDataContainer()
|
||||
TEST.api_ip_availability = utils.TestDataContainer()
|
||||
TEST.api_qos_policies = utils.TestDataContainer()
|
||||
|
||||
# 1st network.
|
||||
network_dict = {'admin_state_up': True,
|
||||
@ -961,3 +963,15 @@ def data(TEST):
|
||||
|
||||
TEST.ip_availability.add(availability)
|
||||
TEST.api_ip_availability.add(availability)
|
||||
|
||||
# qos policies
|
||||
policy_dict = {'id': 'a21dcd22-7189-cccc-aa32-22adafaf16a7',
|
||||
'name': 'policy 1',
|
||||
'tenant_id': '1'}
|
||||
TEST.api_qos_policies.add(policy_dict)
|
||||
TEST.qos_policies.add(neutron.QoSPolicy(policy_dict))
|
||||
policy_dict1 = {'id': 'a21dcd22-7189-ssss-aa32-22adafaf16a7',
|
||||
'name': 'policy 2',
|
||||
'tenant_id': '1'}
|
||||
TEST.api_qos_policies.add(policy_dict1)
|
||||
TEST.qos_policies.add(neutron.QoSPolicy(policy_dict1))
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- The Network QoS panel allows users to view a list of created network
|
||||
policies. This panel displays a table view of the name, id, description
|
||||
and shared status of each policy.
|
Loading…
x
Reference in New Issue
Block a user