Adding Identity NGProjects API
This patch adds some projects-related endpoints to the Nova, Cinder and Neutron REST/Angular APIs. These changes are needed for the angular Identity Projects actions that handle mainly project quota updates. Partially-Implements: blueprint angularize-identity-projects Change-Id: I98b8eb9e5e7bfb0d49a77c00115fe62d412abe21
This commit is contained in:
parent
20bfc93dc5
commit
3945b24062
@ -300,3 +300,32 @@ class DefaultQuotaSets(generic.View):
|
||||
api.cinder.default_quota_update(request, **cinder_data)
|
||||
else:
|
||||
raise rest_utils.AjaxError(501, _('Service Cinder is disabled.'))
|
||||
|
||||
|
||||
@urls.register
|
||||
class QuotaSets(generic.View):
|
||||
"""API for setting quotas for a given project.
|
||||
"""
|
||||
url_regex = r'cinder/quota-sets/(?P<project_id>[0-9a-f]+)$'
|
||||
|
||||
@rest_utils.ajax(data_required=True)
|
||||
def patch(self, request, project_id):
|
||||
"""Update a single project quota data.
|
||||
|
||||
The PATCH data should be an application/json object with the
|
||||
attributes to set to new quota values.
|
||||
|
||||
This method returns HTTP 204 (no content) on success.
|
||||
"""
|
||||
# Filters cinder quota fields
|
||||
disabled_quotas = quotas.get_disabled_quotas(request)
|
||||
|
||||
if api.cinder.is_volume_service_enabled():
|
||||
cinder_data = {
|
||||
key: request.DATA[key] for key in quotas.CINDER_QUOTA_FIELDS
|
||||
if key not in disabled_quotas
|
||||
}
|
||||
|
||||
api.cinder.tenant_quota_update(request, project_id, **cinder_data)
|
||||
else:
|
||||
raise rest_utils.AjaxError(501, _('Service Cinder is disabled.'))
|
||||
|
@ -15,11 +15,13 @@
|
||||
"""API over the neutron service.
|
||||
"""
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.views import generic
|
||||
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.api.rest import urls
|
||||
from openstack_dashboard.api.rest import utils as rest_utils
|
||||
from openstack_dashboard.usage import quotas
|
||||
|
||||
|
||||
@urls.register
|
||||
@ -173,3 +175,62 @@ class Extensions(generic.View):
|
||||
"""
|
||||
result = api.neutron.list_extensions(request)
|
||||
return {'items': [e for e in result]}
|
||||
|
||||
|
||||
class DefaultQuotaSets(generic.View):
|
||||
"""API for getting default quotas for neutron
|
||||
"""
|
||||
url_regex = r'neutron/quota-sets/defaults/$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request):
|
||||
if api.base.is_service_enabled(request, 'network'):
|
||||
quota_set = api.neutron.tenant_quota_get(
|
||||
request, request.user.tenant_id)
|
||||
|
||||
result = [{
|
||||
'display_name': quotas.QUOTA_NAMES.get(
|
||||
quota.name,
|
||||
quota.name.replace('_', ' ').title()
|
||||
) + '',
|
||||
'name': quota.name,
|
||||
'limit': quota.limit
|
||||
} for quota in quota_set]
|
||||
|
||||
return {'items': result}
|
||||
else:
|
||||
raise rest_utils.AjaxError(501, _('Service Neutron is disabled.'))
|
||||
|
||||
|
||||
@urls.register
|
||||
class QuotasSets(generic.View):
|
||||
"""API for setting quotas of a given project.
|
||||
"""
|
||||
url_regex = r'neutron/quotas-sets/(?P<project_id>[0-9a-f]+)$'
|
||||
|
||||
@rest_utils.ajax(data_required=True)
|
||||
def patch(self, request, project_id):
|
||||
"""Update a single project quota data.
|
||||
|
||||
The PATCH data should be an application/json object with the
|
||||
attributes to set to new quota values.
|
||||
|
||||
This method returns HTTP 204 (no content) on success.
|
||||
"""
|
||||
# Filters only neutron quota fields
|
||||
disabled_quotas = quotas.get_disabled_quotas(request)
|
||||
|
||||
if api.base.is_service_enabled(request, 'network') and \
|
||||
api.neutron.is_extension_supported(request, 'quotas'):
|
||||
neutron_data = {
|
||||
key: request.DATA[key] for key in quotas.NEUTRON_QUOTA_FIELDS
|
||||
if key not in disabled_quotas
|
||||
}
|
||||
|
||||
api.neutron.tenant_quota_update(request,
|
||||
project_id,
|
||||
**neutron_data)
|
||||
else:
|
||||
message = _('Service Neutron is disabled or quotas extension not '
|
||||
'available.')
|
||||
raise rest_utils.AjaxError(501, message)
|
||||
|
@ -572,3 +572,51 @@ class DefaultQuotaSets(generic.View):
|
||||
api.nova.default_quota_update(request, **nova_data)
|
||||
else:
|
||||
raise rest_utils.AjaxError(501, _('Service Nova is disabled.'))
|
||||
|
||||
|
||||
@urls.register
|
||||
class EditableQuotaSets(generic.View):
|
||||
"""API for editable quotas.
|
||||
"""
|
||||
url_regex = r'nova/quota-sets/editable/$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request):
|
||||
"""Get a list of editable quota fields.
|
||||
|
||||
The listing result is an object with property "items". Each item
|
||||
is an editable quota. Returns an empty list in case no editable
|
||||
quota is found.
|
||||
"""
|
||||
disabled_quotas = quotas.get_disabled_quotas(request)
|
||||
editable_quotas = [quota for quota in quotas.QUOTA_FIELDS
|
||||
if quota not in disabled_quotas]
|
||||
return {'items': editable_quotas}
|
||||
|
||||
|
||||
@urls.register
|
||||
class QuotaSets(generic.View):
|
||||
"""API for setting quotas for a given project.
|
||||
"""
|
||||
url_regex = r'nova/quota-sets/(?P<project_id>[0-9a-f]+)$'
|
||||
|
||||
@rest_utils.ajax(data_required=True)
|
||||
def patch(self, request, project_id):
|
||||
"""Update a single project quota data.
|
||||
|
||||
The PATCH data should be an application/json object with the
|
||||
attributes to set to new quota values.
|
||||
|
||||
This method returns HTTP 204 (no content) on success.
|
||||
"""
|
||||
disabled_quotas = quotas.get_disabled_quotas(request)
|
||||
|
||||
if api.base.is_service_enabled(request, 'compute'):
|
||||
nova_data = {
|
||||
key: request.DATA[key] for key in quotas.NOVA_QUOTA_FIELDS
|
||||
if key not in disabled_quotas
|
||||
}
|
||||
|
||||
api.nova.tenant_quota_update(request, project_id, **nova_data)
|
||||
else:
|
||||
raise rest_utils.AjaxError(501, _('Service Nova is disabled.'))
|
||||
|
@ -47,7 +47,8 @@
|
||||
getAbsoluteLimits: getAbsoluteLimits,
|
||||
getServices: getServices,
|
||||
getDefaultQuotaSets: getDefaultQuotaSets,
|
||||
setDefaultQuotaSets: setDefaultQuotaSets
|
||||
setDefaultQuotaSets: setDefaultQuotaSets,
|
||||
updateProjectQuota: updateProjectQuota
|
||||
};
|
||||
|
||||
return service;
|
||||
@ -199,8 +200,7 @@
|
||||
var config = params ? {'params': params} : {};
|
||||
return apiService.get('/api/cinder/volumesnapshots/', config)
|
||||
.error(function () {
|
||||
toastService.add('error',
|
||||
gettext('Unable to retrieve the volume snapshots.'));
|
||||
toastService.add('error', gettext('Unable to retrieve the volume snapshots.'));
|
||||
});
|
||||
}
|
||||
|
||||
@ -322,5 +322,24 @@
|
||||
});
|
||||
}
|
||||
|
||||
// Quota Sets
|
||||
|
||||
/**
|
||||
* @name updateProjectQuota
|
||||
* @description
|
||||
* Update a single project quota data.
|
||||
* @param {application/json} quota
|
||||
* A JSON object with the atributes to set to new quota values.
|
||||
* @param {string} projectId
|
||||
* Specifies the id of the project that'll have the quota data updated.
|
||||
*/
|
||||
function updateProjectQuota(quota, projectId) {
|
||||
var url = '/api/cinder/quota-sets/' + projectId;
|
||||
return apiService.patch(url, quota)
|
||||
.error(function() {
|
||||
toastService.add('error', gettext('Unable to update project quota data.'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}());
|
||||
|
@ -158,6 +158,13 @@
|
||||
method: 'patch',
|
||||
path: '/api/cinder/quota-sets/defaults/',
|
||||
error: 'Unable to set the default quotas.'
|
||||
},
|
||||
{ func: 'updateProjectQuota',
|
||||
method: 'patch',
|
||||
path: '/api/cinder/quota-sets/42',
|
||||
data: {'volumes': 42},
|
||||
error: 'Unable to update project quota data.',
|
||||
testInput: [{'volumes': 42}, 42]
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -41,7 +41,9 @@
|
||||
createSubnet: createSubnet,
|
||||
getPorts: getPorts,
|
||||
getAgents: getAgents,
|
||||
getExtensions: getExtensions
|
||||
getExtensions: getExtensions,
|
||||
getDefaultQuotaSets: getDefaultQuotaSets,
|
||||
updateProjectQuota: updateProjectQuota
|
||||
};
|
||||
|
||||
return service;
|
||||
@ -297,6 +299,43 @@
|
||||
toastService.add('error', gettext('Unable to retrieve the extensions.'));
|
||||
});
|
||||
}
|
||||
|
||||
// Default Quota Sets
|
||||
|
||||
/**
|
||||
* @name getDefaultQuotaSets
|
||||
* @description
|
||||
* Get default quotasets
|
||||
*
|
||||
* The listing result is an object with property "items." Each item is
|
||||
* a quota.
|
||||
*
|
||||
*/
|
||||
function getDefaultQuotaSets() {
|
||||
return apiService.get('/api/neutron/quota-sets/defaults/')
|
||||
.error(function() {
|
||||
toastService.add('error', gettext('Unable to retrieve the default quotas.'));
|
||||
});
|
||||
}
|
||||
|
||||
// Quotas Extension
|
||||
|
||||
/**
|
||||
* @name updateProjectQuota
|
||||
* @description
|
||||
* Update a single project quota data.
|
||||
* @param {application/json} quota
|
||||
* A JSON object with the atributes to set to new quota values.
|
||||
* @param {string} projectId
|
||||
* Specifies the id of the project that'll have the quota data updated.
|
||||
*/
|
||||
function updateProjectQuota(quota, projectId) {
|
||||
var url = '/api/neutron/quotas-sets/' + projectId;
|
||||
return apiService.patch(url, quota)
|
||||
.error(function() {
|
||||
toastService.add('error', gettext('Unable to update project quota data.'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}());
|
||||
|
@ -104,6 +104,27 @@
|
||||
"method": "get",
|
||||
"path": "/api/neutron/extensions/",
|
||||
"error": "Unable to retrieve the extensions."
|
||||
},
|
||||
{
|
||||
"func": "getDefaultQuotaSets",
|
||||
"method": "get",
|
||||
"path": "/api/neutron/quota-sets/defaults/",
|
||||
"error": "Unable to retrieve the default quotas."
|
||||
},
|
||||
{
|
||||
"func": "updateProjectQuota",
|
||||
"method": "patch",
|
||||
"path": "/api/neutron/quotas-sets/42",
|
||||
"data": {
|
||||
"network": 42
|
||||
},
|
||||
"error": "Unable to update project quota data.",
|
||||
"testInput": [
|
||||
{
|
||||
"network": 42
|
||||
},
|
||||
42
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -62,7 +62,9 @@
|
||||
updateFlavor: updateFlavor,
|
||||
deleteFlavor: deleteFlavor,
|
||||
getDefaultQuotaSets: getDefaultQuotaSets,
|
||||
setDefaultQuotaSets: setDefaultQuotaSets
|
||||
setDefaultQuotaSets: setDefaultQuotaSets,
|
||||
getEditableQuotas: getEditableQuotas,
|
||||
updateProjectQuota: updateProjectQuota
|
||||
};
|
||||
|
||||
return service;
|
||||
@ -516,7 +518,7 @@
|
||||
// Default Quota Sets
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.nova.getDefaultQuotaSets
|
||||
* @name getDefaultQuotaSets
|
||||
* @description
|
||||
* Get default quotasets
|
||||
*
|
||||
@ -532,7 +534,7 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.nova.setDefaultQuotaSets
|
||||
* @name setDefaultQuotaSets
|
||||
* @description
|
||||
* Set default quotasets
|
||||
*
|
||||
@ -544,6 +546,40 @@
|
||||
});
|
||||
}
|
||||
|
||||
// Quota Sets
|
||||
|
||||
/**
|
||||
* @name getEditableQuotas
|
||||
* @description
|
||||
* Get a list of editable quota fields.
|
||||
* The listing result is an object with property "items." Each item is
|
||||
* an editable quota field.
|
||||
*
|
||||
*/
|
||||
function getEditableQuotas() {
|
||||
return apiService.get('/api/nova/quota-sets/editable/')
|
||||
.error(function() {
|
||||
toastService.add('error', gettext('Unable to retrieve the editable quotas.'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @name updateProjectQuota
|
||||
* @description
|
||||
* Update a single project quota data.
|
||||
* @param {application/json} quota
|
||||
* A JSON object with the atributes to set to new quota values.
|
||||
* @param {string} projectId
|
||||
* Specifies the id of the project that'll have the quota data updated.
|
||||
*/
|
||||
function updateProjectQuota(quota, projectId) {
|
||||
var url = '/api/nova/quota-sets/' + projectId;
|
||||
return apiService.patch(url, quota)
|
||||
.error(function() {
|
||||
toastService.add('error', gettext('Unable to update project quota data.'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name getCreateKeypairUrl
|
||||
|
@ -343,6 +343,27 @@
|
||||
],
|
||||
"path": "/api/nova/quota-sets/defaults/",
|
||||
"error": "Unable to set the default quotas."
|
||||
},
|
||||
{
|
||||
"func": "getEditableQuotas",
|
||||
"method": "get",
|
||||
"path": "/api/nova/quota-sets/editable/",
|
||||
"error": "Unable to retrieve the editable quotas."
|
||||
},
|
||||
{
|
||||
"func": "updateProjectQuota",
|
||||
"method": "patch",
|
||||
"path": "/api/nova/quota-sets/42",
|
||||
"data": {
|
||||
"cores": 42
|
||||
},
|
||||
"error": "Unable to update project quota data.",
|
||||
"testInput": [
|
||||
{
|
||||
"cores": 42
|
||||
},
|
||||
42
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -346,3 +346,55 @@ class CinderRestTestCase(test.TestCase):
|
||||
'"Service Cinder is disabled."')
|
||||
|
||||
cc.default_quota_update.assert_not_called()
|
||||
|
||||
@mock.patch.object(cinder.api, 'cinder')
|
||||
@mock.patch.object(cinder, 'quotas')
|
||||
def test_quota_sets_patch(self, qc, cc):
|
||||
quota_set = self.cinder_quotas.list()[0]
|
||||
quota_data = {}
|
||||
|
||||
for quota in quota_set:
|
||||
quota_data[quota.name] = quota.limit
|
||||
|
||||
request = self.mock_rest_request(body='''
|
||||
{"volumes": "15", "snapshots": "5000",
|
||||
"gigabytes": "5", "cores": "10"}
|
||||
''')
|
||||
|
||||
qc.get_disabled_quotas.return_value = []
|
||||
qc.CINDER_QUOTA_FIELDS = (n for n in quota_data)
|
||||
cc.is_volume_service_enabled.return_value = True
|
||||
|
||||
response = cinder.QuotaSets().patch(request, 'spam123')
|
||||
|
||||
self.assertStatusCode(response, 204)
|
||||
self.assertEqual(response.content.decode('utf-8'), '')
|
||||
cc.tenant_quota_update.assert_called_once_with(request, 'spam123',
|
||||
volumes='15',
|
||||
snapshots='5000',
|
||||
gigabytes='5')
|
||||
|
||||
@mock.patch.object(cinder.api, 'cinder')
|
||||
@mock.patch.object(cinder, 'quotas')
|
||||
def test_quota_sets_when_service_is_disabled(self, qc, cc):
|
||||
quota_set = self.cinder_quotas.list()[0]
|
||||
quota_data = {}
|
||||
|
||||
for quota in quota_set:
|
||||
quota_data[quota.name] = quota.limit
|
||||
|
||||
request = self.mock_rest_request(body='''
|
||||
{"volumes": "15", "snapshots": "5000",
|
||||
"gigabytes": "5", "cores": "10"}
|
||||
''')
|
||||
|
||||
qc.get_disabled_quotas.return_value = []
|
||||
qc.CINDER_QUOTA_FIELDS = (n for n in quota_data)
|
||||
cc.is_volume_service_enabled.return_value = False
|
||||
|
||||
response = cinder.QuotaSets().patch(request, 'spam123')
|
||||
|
||||
self.assertStatusCode(response, 501)
|
||||
self.assertEqual(response.content.decode('utf-8'),
|
||||
'"Service Cinder is disabled."')
|
||||
cc.tenant_quota_update.assert_not_called()
|
||||
|
@ -16,6 +16,7 @@
|
||||
import mock
|
||||
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.api import base
|
||||
from openstack_dashboard.api.rest import neutron
|
||||
from openstack_dashboard.test import helpers as test
|
||||
from openstack_dashboard.test.test_data import neutron_data
|
||||
@ -174,6 +175,109 @@ class NeutronExtensionsTestCase(test.TestCase):
|
||||
nc.list_extensions.assert_called_once_with(request)
|
||||
|
||||
|
||||
class NeutronDefaultQuotasTestCase(test.TestCase):
|
||||
@test.create_stubs({base: ('is_service_enabled',)})
|
||||
@mock.patch.object(neutron.api, 'neutron')
|
||||
def test_quotas_sets_defaults_get_when_service_is_enabled(self, client):
|
||||
filters = {'user': {'tenant_id': 'tenant'}}
|
||||
request = self.mock_rest_request(**{'GET': dict(filters)})
|
||||
|
||||
base.is_service_enabled(request, 'network').AndReturn(True)
|
||||
|
||||
client.tenant_quota_get.return_value = [
|
||||
base.Quota("network", 100),
|
||||
base.Quota("q2", 101)]
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
response = neutron.DefaultQuotaSets().get(request)
|
||||
self.assertStatusCode(response, 200)
|
||||
self.assertItemsCollectionEqual(response, [
|
||||
{'limit': 100, 'display_name': 'Networks', 'name': 'network'},
|
||||
{'limit': 101, 'display_name': 'Q2', 'name': 'q2'}])
|
||||
|
||||
client.tenant_quota_get.assert_called_once_with(
|
||||
request,
|
||||
request.user.tenant_id)
|
||||
|
||||
@test.create_stubs({neutron.api.base: ('is_service_enabled',)})
|
||||
@mock.patch.object(neutron.api, 'neutron')
|
||||
def test_quota_sets_defaults_get_when_service_is_disabled(self, client):
|
||||
filters = {'user': {'tenant_id': 'tenant'}}
|
||||
request = self.mock_rest_request(**{'GET': dict(filters)})
|
||||
|
||||
base.is_service_enabled(request, 'network').AndReturn(False)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
response = neutron.DefaultQuotaSets().get(request)
|
||||
self.assertStatusCode(response, 501)
|
||||
self.assertEqual(response.content.decode('utf-8'),
|
||||
'"Service Neutron is disabled."')
|
||||
|
||||
client.tenant_quota_get.assert_not_called()
|
||||
|
||||
|
||||
class NeutronQuotaSetsTestCase(test.TestCase):
|
||||
def setUp(self):
|
||||
super(NeutronQuotaSetsTestCase, self).setUp()
|
||||
|
||||
quota_set = self.neutron_quotas.list()[0]
|
||||
self._quota_data = {}
|
||||
|
||||
for quota in quota_set:
|
||||
self._quota_data[quota.name] = quota.limit
|
||||
|
||||
@mock.patch.object(neutron, 'quotas')
|
||||
@mock.patch.object(neutron.api, 'neutron')
|
||||
@mock.patch.object(neutron.api, 'base')
|
||||
def test_quotas_sets_patch(self, bc, nc, qc):
|
||||
request = self.mock_rest_request(body='''
|
||||
{"network": "5", "subnet": "5", "port": "50",
|
||||
"router": "5", "floatingip": "50",
|
||||
"security_group": "5", "security_group_rule": "50",
|
||||
"volumes": "5", "cores": "50"}
|
||||
''')
|
||||
|
||||
qc.get_disabled_quotas.return_value = []
|
||||
qc.NEUTRON_QUOTA_FIELDS = (n for n in self._quota_data)
|
||||
bc.is_service_enabled.return_value = True
|
||||
nc.is_extension_supported.return_value = True
|
||||
|
||||
response = neutron.QuotasSets().patch(request, 'spam123')
|
||||
|
||||
self.assertStatusCode(response, 204)
|
||||
self.assertEqual(response.content.decode('utf-8'), '')
|
||||
nc.tenant_quota_update.assert_called_once_with(
|
||||
request, 'spam123', network='5',
|
||||
subnet='5', port='50', router='5',
|
||||
floatingip='50', security_group='5',
|
||||
security_group_rule='50')
|
||||
|
||||
@mock.patch.object(neutron, 'quotas')
|
||||
@mock.patch.object(neutron.api, 'neutron')
|
||||
@mock.patch.object(neutron.api, 'base')
|
||||
def test_quotas_sets_patch_when_service_is_disabled(self, bc, nc, qc):
|
||||
request = self.mock_rest_request(body='''
|
||||
{"network": "5", "subnet": "5", "port": "50",
|
||||
"router": "5", "floatingip": "50",
|
||||
"security_group": "5", "security_group_rule": "50",
|
||||
"volumes": "5", "cores": "50"}
|
||||
''')
|
||||
|
||||
qc.get_disabled_quotas.return_value = []
|
||||
qc.NEUTRON_QUOTA_FIELDS = (n for n in self._quota_data)
|
||||
bc.is_service_enabled.return_value = False
|
||||
|
||||
response = neutron.QuotasSets().patch(request, 'spam123')
|
||||
message = \
|
||||
'"Service Neutron is disabled or quotas extension not available."'
|
||||
|
||||
self.assertStatusCode(response, 501)
|
||||
self.assertEqual(response.content.decode('utf-8'), message)
|
||||
nc.tenant_quota_update.assert_not_called()
|
||||
|
||||
|
||||
def mock_obj_to_dict(r):
|
||||
return mock.Mock(**{'to_dict.return_value': r})
|
||||
|
||||
|
@ -769,3 +769,79 @@ class NovaRestTestCase(test.TestCase):
|
||||
'"Service Nova is disabled."')
|
||||
|
||||
nc.default_quota_update.assert_not_called()
|
||||
|
||||
@mock.patch.object(nova, 'quotas')
|
||||
@mock.patch.object(nova.api, 'nova')
|
||||
def test_editable_quotas_get(self, nc, qc):
|
||||
disabled_quotas = ['floating_ips', 'fixed_ips',
|
||||
'security_groups', 'security_group_rules']
|
||||
editable_quotas = ['cores', 'volumes', 'network', 'fixed_ips']
|
||||
qc.get_disabled_quotas.return_value = disabled_quotas
|
||||
qc.QUOTA_FIELDS = editable_quotas
|
||||
request = self.mock_rest_request()
|
||||
response = nova.EditableQuotaSets().get(request)
|
||||
self.assertStatusCode(response, 200)
|
||||
self.assertItemsCollectionEqual(response,
|
||||
['cores', 'volumes', 'network'])
|
||||
|
||||
@mock.patch.object(nova.api, 'nova')
|
||||
@mock.patch.object(nova.api, 'base')
|
||||
@mock.patch.object(nova, 'quotas')
|
||||
def test_quota_sets_patch(self, qc, bc, nc):
|
||||
quota_data = dict(cores='15', instances='5',
|
||||
ram='50000', metadata_items='150',
|
||||
injected_files='5',
|
||||
injected_file_content_bytes='10240',
|
||||
floating_ips='50', fixed_ips='5',
|
||||
security_groups='10',
|
||||
security_group_rules='100')
|
||||
|
||||
request = self.mock_rest_request(body='''
|
||||
{"cores": "15", "ram": "50000", "instances": "5",
|
||||
"metadata_items": "150", "injected_files": "5",
|
||||
"injected_file_content_bytes": "10240", "floating_ips": "50",
|
||||
"fixed_ips": "5", "security_groups": "10" ,
|
||||
"security_group_rules": "100", "volumes": "10"}
|
||||
''')
|
||||
|
||||
qc.get_disabled_quotas.return_value = []
|
||||
qc.NOVA_QUOTA_FIELDS = (n for n in quota_data)
|
||||
bc.is_service_enabled.return_value = True
|
||||
|
||||
response = nova.QuotaSets().patch(request, 'spam123')
|
||||
|
||||
self.assertStatusCode(response, 204)
|
||||
self.assertEqual(response.content.decode('utf-8'), '')
|
||||
nc.tenant_quota_update.assert_called_once_with(
|
||||
request, 'spam123', **quota_data)
|
||||
|
||||
@mock.patch.object(nova.api, 'nova')
|
||||
@mock.patch.object(nova.api, 'base')
|
||||
@mock.patch.object(nova, 'quotas')
|
||||
def test_quota_sets_patch_when_service_is_disabled(self, qc, bc, nc):
|
||||
quota_data = dict(cores='15', instances='5',
|
||||
ram='50000', metadata_items='150',
|
||||
injected_files='5',
|
||||
injected_file_content_bytes='10240',
|
||||
floating_ips='50', fixed_ips='5',
|
||||
security_groups='10',
|
||||
security_group_rules='100')
|
||||
|
||||
request = self.mock_rest_request(body='''
|
||||
{"cores": "15", "ram": "50000", "instances": "5",
|
||||
"metadata_items": "150", "injected_files": "5",
|
||||
"injected_file_content_bytes": "10240", "floating_ips": "50",
|
||||
"fixed_ips": "5", "security_groups": "10" ,
|
||||
"security_group_rules": "100", "volumes": "10"}
|
||||
''')
|
||||
|
||||
qc.get_disabled_quotas.return_value = []
|
||||
qc.NOVA_QUOTA_FIELDS = (n for n in quota_data)
|
||||
bc.is_service_enabled.return_value = False
|
||||
|
||||
response = nova.QuotaSets().patch(request, 'spam123')
|
||||
|
||||
self.assertStatusCode(response, 501)
|
||||
self.assertEqual(response.content.decode('utf-8'),
|
||||
'"Service Nova is disabled."')
|
||||
nc.tenant_quota_update.assert_not_called()
|
||||
|
Loading…
Reference in New Issue
Block a user