Add Create QoS operation to Network QoS Panel

Enabled Network QoS panel and added a button for
creating a new network qos policy with parameters
name(string), description(maxlen-255), and
shared(checkbox)

Partially-Implements: https://blueprints.launchpad.net/horizon/+spec/create-network-qos-policy

Change-Id: Ifabfac7553ddbb65fe387187da5dd2fafad31351
This commit is contained in:
zitptan 2021-07-02 17:59:45 +05:30 committed by Nitish Venkata Patcherla
parent fbf4036db3
commit 1800750804
11 changed files with 388 additions and 3 deletions

View File

@ -301,6 +301,20 @@ class QoSPolicies(generic.View):
tenant_id=request.user.project_id)
return {'items': [p.to_dict() for p in result]}
@rest_utils.ajax(data_required=True)
def post(self, request):
"""Create a Network QoS policy.
Create a qos policy using parameters supplied in the POST
application/json object. The "name" (string) parameter is required.
This method returns the new qos policy object on success.
"""
qospolicy = api.neutron.policy_create(request, **request.DATA)
return rest_utils.CreatedResponse(
'/api/neutron/qos_policies/%s' % qospolicy.id,
qospolicy.to_dict()
)
@urls.register
class QoSPolicy(generic.View):

View File

@ -8,6 +8,3 @@ PANEL_GROUP = 'network'
# Python panel class of the PANEL to be added.
ADD_PANEL = ('openstack_dashboard.dashboards.project.network_qos'
'.panel.NetworkQoS')
# Will default to disabled until the feature is completed.
DISABLED = True

View File

@ -31,17 +31,30 @@
registerQosActions.$inject = [
'horizon.framework.conf.resource-type-registry.service',
'horizon.app.core.network_qos.actions.create.service',
'horizon.app.core.network_qos.actions.delete.service',
'horizon.app.core.network_qos.resourceType'
];
function registerQosActions(
registry,
createService,
deleteService,
qosResourceTypeCode
) {
var qosResourceType = registry.getResourceType(qosResourceTypeCode);
qosResourceType.globalActions
.append({
id: 'createPolicyAction',
service: createService,
template: {
text: gettext('Create Policy'),
type: 'create'
}
}
);
qosResourceType.itemActions
.append({
id: 'deletePolicyAction',

View File

@ -23,6 +23,11 @@
registry = $injector.get('horizon.framework.conf.resource-type-registry.service');
}));
it('registers Create Policy as a global action', function() {
var actions = registry.getResourceType('OS::Neutron::QoSPolicy').globalActions;
expect(actionHasId(actions, 'createPolicyAction')).toBe(true);
});
it('registers Delete Policy as an item action', function() {
var actions = registry.getResourceType('OS::Neutron::QoSPolicy').itemActions;
expect(actionHasId(actions, 'deletePolicyAction')).toBe(true);

View File

@ -0,0 +1,89 @@
/*
* 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.actions.create.service
*
* @description
* Provides all of the actions for creating network qos policy.
*/
angular
.module('horizon.app.core.network_qos')
.factory('horizon.app.core.network_qos.actions.create.service', createService);
createService.$inject = [
'horizon.app.core.openstack-service-api.neutron',
'horizon.app.core.openstack-service-api.policy',
'horizon.app.core.network_qos.actions.workflow.service',
'horizon.app.core.network_qos.resourceType',
'horizon.framework.widgets.form.ModalFormService',
'horizon.framework.widgets.toast.service',
'horizon.framework.util.actions.action-result.service'
];
function createService(
neutronAPI,
policy,
workflow,
resourceType,
modalFormService,
toast,
actionResultService
) {
var service = {
allowed: allowed,
perform: perform,
submit: submit
};
return service;
//////
function allowed() {
return policy.ifAllowed(
{rules: [
['network', 'create_qos_policy']
]}
);
}
function perform() {
var createPolicy = workflow.init();
createPolicy.title = gettext('Create QoS Policy');
return modalFormService.open(createPolicy).then(submit);
}
function submit(context) {
var data = {name: context.model.name, description: context.model.description,
shared: context.model.shared};
return neutronAPI.createNetworkQoSPolicy(data).then(onCreateNetworkQoSPolicy);
}
function onCreateNetworkQoSPolicy(response) {
var qospolicy = response.data;
toast.add('success', interpolate(
gettext('QoS Policy %s was successfully created.'), [qospolicy.name]));
return actionResultService.getActionResult()
.created(resourceType, qospolicy.id)
.result;
}
}
})();

View File

@ -0,0 +1,80 @@
/*
* 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.actions.create.service', function() {
var $q, $scope, neutronAPI, service, modalFormService, policyAPI, toast, resType;
///////////////////////
beforeEach(module('horizon.framework'));
beforeEach(module('horizon.app.core'));
beforeEach(module('horizon.app.core.network_qos'));
beforeEach(inject(function($injector, _$rootScope_, _$q_) {
$scope = _$rootScope_.$new();
$q = _$q_;
service = $injector.get('horizon.app.core.network_qos.actions.create.service');
toast = $injector.get('horizon.framework.widgets.toast.service');
modalFormService = $injector.get('horizon.framework.widgets.form.ModalFormService');
neutronAPI = $injector.get('horizon.app.core.openstack-service-api.neutron');
policyAPI = $injector.get('horizon.app.core.openstack-service-api.policy');
resType = $injector.get('horizon.app.core.network_qos.resourceType');
}));
it('should check if the user is allowed to create netwrok qos policy', function() {
spyOn(policyAPI, 'ifAllowed').and.callThrough();
var allowed = service.allowed();
expect(allowed).toBeTruthy();
expect(policyAPI.ifAllowed).toHaveBeenCalledWith(
{ rules: [['network', 'create_qos_policy']] });
});
it('should open the modal', function() {
spyOn(modalFormService, 'open').and.returnValue($q.defer().promise);
spyOn(neutronAPI, 'createNetworkQoSPolicy').and.returnValue($q.defer().promise);
service.perform();
$scope.$apply();
expect(modalFormService.open).toHaveBeenCalled();
});
it('should submit create neutron qos request to neutron', function() {
var deferred = $q.defer();
spyOn(neutronAPI, 'createNetworkQoSPolicy').and.returnValue(deferred.promise);
spyOn(toast, 'add').and.callFake(angular.noop);
var handler = jasmine.createSpyObj('handler', ['success']);
deferred.resolve({data: {name: 'qos1', id: '1'}});
service.submit({model: {name: 'qos', description: undefined, shared: 'yes'}})
.then(handler.success);
$scope.$apply();
expect(neutronAPI.createNetworkQoSPolicy).toHaveBeenCalledWith(
{name: 'qos', description: undefined, shared: 'yes'});
expect(toast.add).toHaveBeenCalledWith(
'success', 'QoS Policy qos1 was successfully created.');
expect(handler.success).toHaveBeenCalled();
var result = handler.success.calls.first().args[0];
expect(result.created).toEqual([{type: resType, id: '1'}]);
});
});
})();

View File

@ -0,0 +1,84 @@
/*
* 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 factory
* @name horizon.app.core.network_qos.actions.workflow.service
* @ngController
*
* @description
* Workflow for creating network qos policy
*/
angular
.module('horizon.app.core.network_qos.actions')
.factory('horizon.app.core.network_qos.actions.workflow.service', NetworkQosWorkflow);
function NetworkQosWorkflow() {
var workflow = {
init: init
};
function init() {
var schema = {
type: 'object',
properties: {
name: {
title: gettext('Name'),
type: 'string'
},
description: {
title: gettext('Description'),
type: 'string',
maxLength: 255
},
shared: {
title: gettext('Shared'),
type: 'boolean',
default: false
}
},
required: ['name']
};
var form = [
"name",
{
key: "description",
type: "textarea"
},
{
key: "shared",
type: "checkbox"
}
];
var model = {};
var config = {
schema: schema,
form: form,
model: model
};
return config;
}
return workflow;
}
})();

View File

@ -0,0 +1,51 @@
/*
* 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.actions.workflow.service', function() {
var $q, $scope, workflow, service;
beforeEach(module('horizon.framework'));
beforeEach(module('horizon.app.core'));
beforeEach(module('horizon.app.core.network_qos'));
beforeEach(inject(function($injector, _$rootScope_, _$q_) {
$scope = _$rootScope_.$new();
$q = _$q_;
workflow = $injector.get('horizon.app.core.network_qos.actions.workflow.service');
service = $injector.get('horizon.app.core.network_qos.actions.create.service');
}));
function testInitWorkflow() {
var deferred = $q.defer();
spyOn(service, 'perform').and.returnValue(deferred.promise);
deferred.resolve({'a1': 'n1'});
var config = workflow.init();
$scope.$apply();
expect(config.schema).toBeDefined();
expect(config.form).toBeDefined();
expect(config.model).toBeDefined();
return config;
}
it('should create workflow config for creation', function() {
testInitWorkflow();
});
});
})();

View File

@ -38,6 +38,7 @@
createNetwork: createNetwork,
createSubnet: createSubnet,
createTrunk: createTrunk,
createNetworkQoSPolicy: createNetworkQoSPolicy,
deletePolicy: deletePolicy,
deleteTrunk: deleteTrunk,
getAgents: getAgents,
@ -391,6 +392,42 @@
});
}
/**
* @name createNetworkQoSPolicy
* @description
* Create a new network qos policy.
* @returns {Object} The new network qos policy object on success.
*
* @param {Object} newQosPolicy
* The network qos policy to create. Required.
*
* Example new qos policy object
* {
* "name": "myNewNetworkQoSPolicy",
* "description": "new network qos policy",
* "shared": true,
* }
*
* Description of properties on the qos policy object
*
* @property {string} newQosPolicy.name
* The name of the new network qos policy. Required.
*
* @property {string} newQosPolicy.description
* The description of the qos policy. Optional.
*
* @property {boolean} newQosPolicy.shared
* Indicates whether this network qos policy is shared across all other projects.
* By default, it is unchecked (false). Optional.
*
*/
function createNetworkQoSPolicy(newQosPolicy) {
return apiService.post('/api/neutron/qos_policies/', newQosPolicy)
.error(function () {
toastService.add('error', gettext('Unable to create the QoS Policy.'));
});
}
/**
* @name deletePolicy
* @description

View File

@ -311,6 +311,16 @@
],
"error": "Unable to retrieve the qos policies."
},
{
"func": "createNetworkQoSPolicy",
"method": "post",
"path": "/api/neutron/qos_policies/",
"data": "new network qos policy",
"error": "Unable to create the QoS Policy.",
"testInput": [
"new network qos policy"
]
},
{
"func": "deletePolicy",
"method": "delete",

View File

@ -0,0 +1,5 @@
---
features:
- |
Add "Create Network QoS Policy" button to QoS Policy Panel.
From Horizon users can now create network qos policy.