Skip to content

Commit

Permalink
Fix a issue on retrieving default quota in Create Project
Browse files Browse the repository at this point in the history
quota names for security group are different between nova and neutron,
so the same appoach can be used for floating IP. This commit reverts
the change in get_default_quota_data in commit c44552f and changes
get_disabled_quotas to determine security group and rules quotas come
from nova or neutron.

Change-Id: I9e39ac99f1e8c7ccdce64b2e2ab79615cac50892
Closes-Bug: #1235053
(cherry picked from commit 9fa87da)
  • Loading branch information
amotoki authored and jpichon committed Oct 8, 2013
1 parent 64235fd commit 27873f7
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 31 deletions.
5 changes: 4 additions & 1 deletion openstack_dashboard/dashboards/admin/defaults/tests.py
Expand Up @@ -103,11 +103,14 @@ def _get_quota_info(self, quota):

@test.create_stubs({api.nova: ('default_quota_update', ),
api.cinder: ('default_quota_update', ),
quotas: ('get_default_quota_data', )})
quotas: ('get_default_quota_data',
'get_disabled_quotas')})
def test_update_default_quotas(self):
quota = self.quotas.first()

# init
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
.AndReturn(self.disabled_quotas.first())
quotas.get_default_quota_data(IsA(http.HttpRequest)).AndReturn(quota)

# update some fields
Expand Down
72 changes: 60 additions & 12 deletions openstack_dashboard/dashboards/admin/projects/tests.py
Expand Up @@ -133,6 +133,8 @@ def _get_all_groups(self, domain_id):
'user_list',
'group_list',
'role_list'),
api.base: ('is_service_enabled',),
api.neutron: ('is_extension_supported',),
quotas: ('get_default_quota_data',)})
def test_add_project_get(self):
quota = self.quotas.first()
Expand All @@ -144,8 +146,14 @@ def test_add_project_get(self):
roles = self.roles.list()

# init
api.base.is_service_enabled(IsA(http.HttpRequest), 'network') \
.MultipleTimes().AndReturn(True)
api.base.is_service_enabled(IsA(http.HttpRequest), 'volume') \
.MultipleTimes().AndReturn(True)
api.keystone.get_default_domain(IsA(http.HttpRequest)) \
.AndReturn(default_domain)
api.neutron.is_extension_supported(
IsA(http.HttpRequest), 'security-group').AndReturn(True)
quotas.get_default_quota_data(IsA(http.HttpRequest)).AndReturn(quota)

api.keystone.get_default_role(IsA(http.HttpRequest)) \
Expand Down Expand Up @@ -203,6 +211,8 @@ def test_add_project_get_with_neutron(self):
.AndReturn(quota)
api.neutron.is_extension_supported(IsA(http.HttpRequest), 'quotas') \
.MultipleTimes().AndReturn(True)
api.neutron.is_extension_supported(
IsA(http.HttpRequest), 'security-group').AndReturn(True)
api.neutron.tenant_quota_get(IsA(http.HttpRequest),
tenant_id=self.tenant.id) \
.AndReturn(neutron_quotas)
Expand Down Expand Up @@ -240,7 +250,8 @@ def test_add_project_get_with_neutron(self):
'group_list',
'role_list',
'domain_get'),
quotas: ('get_default_quota_data',),
quotas: ('get_default_quota_data',
'get_disabled_quotas'),
api.cinder: ('tenant_quota_update',),
api.nova: ('tenant_quota_update',)})
def test_add_project_post(self):
Expand All @@ -254,6 +265,8 @@ def test_add_project_post(self):
roles = self.roles.list()

# init
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
.AndReturn(self.disabled_quotas.first())
quotas.get_default_quota_data(IsA(http.HttpRequest)).AndReturn(quota)

api.keystone.get_default_role(IsA(http.HttpRequest)) \
Expand Down Expand Up @@ -325,6 +338,8 @@ def test_add_project_post_with_neutron(self):
neutron_updated_quota = dict([(key, quota_data.get(key).limit)
for key in quotas.NEUTRON_QUOTA_FIELDS])

api.neutron.is_extension_supported(
IsA(http.HttpRequest), 'security-group').AndReturn(True)
api.neutron.is_extension_supported(IsA(http.HttpRequest), 'quotas') \
.MultipleTimes().AndReturn(True)
api.neutron.tenant_quota_update(IsA(http.HttpRequest),
Expand All @@ -337,7 +352,8 @@ def test_add_project_post_with_neutron(self):
'group_list',
'get_default_domain',
'get_default_role'),
quotas: ('get_default_quota_data',)})
quotas: ('get_default_quota_data',
'get_disabled_quotas')})
def test_add_project_quota_defaults_error(self):
default_role = self.roles.first()
default_domain = self._get_default_domain()
Expand All @@ -349,6 +365,8 @@ def test_add_project_quota_defaults_error(self):
# init
api.keystone.get_default_domain(IsA(http.HttpRequest)) \
.AndReturn(default_domain)
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
.AndReturn(self.disabled_quotas.first())
quotas.get_default_quota_data(IsA(http.HttpRequest)) \
.AndRaise(self.exceptions.nova)

Expand Down Expand Up @@ -381,7 +399,8 @@ def test_add_project_quota_defaults_error_domain(self):
'group_list',
'get_default_domain',
'get_default_role'),
quotas: ('get_default_quota_data',)})
quotas: ('get_default_quota_data',
'get_disabled_quotas')})
def test_add_project_tenant_create_error(self):
project = self.tenants.first()
quota = self.quotas.first()
Expand All @@ -395,6 +414,8 @@ def test_add_project_tenant_create_error(self):
# init
api.keystone.get_default_domain(IsA(http.HttpRequest)) \
.AndReturn(default_domain)
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
.AndReturn(self.disabled_quotas.first())
quotas.get_default_quota_data(IsA(http.HttpRequest)).AndReturn(quota)

api.keystone.get_default_role(IsA(http.HttpRequest)) \
Expand Down Expand Up @@ -435,7 +456,8 @@ def test_add_project_tenant_create_error_domain(self):
'get_default_domain',
'get_default_role',
'add_tenant_user_role'),
quotas: ('get_default_quota_data',),
quotas: ('get_default_quota_data',
'get_disabled_quotas'),
api.nova: ('tenant_quota_update',)})
def test_add_project_quota_update_error(self):
project = self.tenants.first()
Expand All @@ -450,6 +472,8 @@ def test_add_project_quota_update_error(self):
# init
api.keystone.get_default_domain(IsA(http.HttpRequest)) \
.AndReturn(default_domain)
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
.AndReturn(self.disabled_quotas.first())
quotas.get_default_quota_data(IsA(http.HttpRequest)).AndReturn(quota)

api.keystone.get_default_role(IsA(http.HttpRequest)) \
Expand Down Expand Up @@ -516,7 +540,8 @@ def test_add_project_quota_update_error_domain(self):
'get_default_domain',
'get_default_role',
'add_tenant_user_role'),
quotas: ('get_default_quota_data',),
quotas: ('get_default_quota_data',
'get_disabled_quotas'),
api.cinder: ('tenant_quota_update',),
api.nova: ('tenant_quota_update',)})
def test_add_project_user_update_error(self):
Expand All @@ -532,6 +557,8 @@ def test_add_project_user_update_error(self):
# init
api.keystone.get_default_domain(IsA(http.HttpRequest)) \
.AndReturn(default_domain)
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
.AndReturn(self.disabled_quotas.first())
quotas.get_default_quota_data(IsA(http.HttpRequest)).AndReturn(quota)

api.keystone.get_default_role(IsA(http.HttpRequest)) \
Expand Down Expand Up @@ -596,7 +623,8 @@ def test_add_project_user_update_error_domain(self):
'group_list',
'get_default_domain',
'get_default_role'),
quotas: ('get_default_quota_data',)})
quotas: ('get_default_quota_data',
'get_disabled_quotas')})
def test_add_project_missing_field_error(self):
project = self.tenants.first()
quota = self.quotas.first()
Expand All @@ -610,6 +638,8 @@ def test_add_project_missing_field_error(self):
# init
api.keystone.get_default_domain(IsA(http.HttpRequest)) \
.AndReturn(default_domain)
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
.AndReturn(self.disabled_quotas.first())
quotas.get_default_quota_data(IsA(http.HttpRequest)).AndReturn(quota)

api.keystone.get_default_role(IsA(http.HttpRequest)) \
Expand Down Expand Up @@ -683,7 +713,8 @@ def _get_proj_groups(self, project_id):
'roles_for_group',
'group_list',
'role_list'),
quotas: ('get_tenant_quota_data',)})
quotas: ('get_tenant_quota_data',
'get_disabled_quotas')})
def test_update_project_get(self):
project = self.tenants.first()
quota = self.quotas.first()
Expand All @@ -699,6 +730,8 @@ def test_update_project_get(self):
.AndReturn(project)
api.keystone.domain_get(IsA(http.HttpRequest), domain_id) \
.AndReturn(self.domain)
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
.AndReturn(self.disabled_quotas.first())
quotas.get_tenant_quota_data(IsA(http.HttpRequest),
tenant_id=self.tenant.id) \
.AndReturn(quota)
Expand Down Expand Up @@ -764,7 +797,8 @@ def test_update_project_get(self):
'role_list'),
api.nova: ('tenant_quota_update',),
api.cinder: ('tenant_quota_update',),
quotas: ('get_tenant_quota_data',)})
quotas: ('get_tenant_quota_data',
'get_disabled_quotas')})
def test_update_project_save(self):
project = self.tenants.first()
quota = self.quotas.first()
Expand All @@ -782,6 +816,8 @@ def test_update_project_save(self):
.AndReturn(project)
api.keystone.domain_get(IsA(http.HttpRequest), domain_id) \
.AndReturn(self.domain)
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
.AndReturn(self.disabled_quotas.first())
quotas.get_tenant_quota_data(IsA(http.HttpRequest),
tenant_id=self.tenant.id) \
.AndReturn(quota)
Expand Down Expand Up @@ -993,7 +1029,8 @@ def test_update_project_get_error(self):
'add_group_role',
'group_list',
'role_list'),
quotas: ('get_tenant_quota_data',),
quotas: ('get_tenant_quota_data',
'get_disabled_quotas'),
api.nova: ('tenant_quota_update',)})
def test_update_project_tenant_update_error(self):
project = self.tenants.first()
Expand All @@ -1011,6 +1048,8 @@ def test_update_project_tenant_update_error(self):
.AndReturn(project)
api.keystone.domain_get(IsA(http.HttpRequest), domain_id) \
.AndReturn(self.domain)
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
.AndReturn(self.disabled_quotas.first())
quotas.get_tenant_quota_data(IsA(http.HttpRequest),
tenant_id=self.tenant.id) \
.AndReturn(quota)
Expand Down Expand Up @@ -1094,7 +1133,8 @@ def test_update_project_tenant_update_error(self):
'add_group_role',
'group_list',
'role_list'),
quotas: ('get_tenant_quota_data',),
quotas: ('get_tenant_quota_data',
'get_disabled_quotas'),
api.nova: ('tenant_quota_update',)})
def test_update_project_quota_update_error(self):
project = self.tenants.first()
Expand All @@ -1113,6 +1153,8 @@ def test_update_project_quota_update_error(self):
.AndReturn(project)
api.keystone.domain_get(IsA(http.HttpRequest), domain_id) \
.AndReturn(self.domain)
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
.AndReturn(self.disabled_quotas.first())
quotas.get_tenant_quota_data(IsA(http.HttpRequest),
tenant_id=self.tenant.id) \
.AndReturn(quota)
Expand Down Expand Up @@ -1255,7 +1297,8 @@ def test_update_project_quota_update_error(self):
'add_group_role',
'group_list',
'role_list'),
quotas: ('get_tenant_quota_data',)})
quotas: ('get_tenant_quota_data',
'get_disabled_quotas')})
def test_update_project_member_update_error(self):
project = self.tenants.first()
quota = self.quotas.first()
Expand All @@ -1272,6 +1315,8 @@ def test_update_project_member_update_error(self):
.AndReturn(project)
api.keystone.domain_get(IsA(http.HttpRequest), domain_id) \
.AndReturn(self.domain)
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
.AndReturn(self.disabled_quotas.first())
quotas.get_tenant_quota_data(IsA(http.HttpRequest),
tenant_id=self.tenant.id) \
.AndReturn(quota)
Expand Down Expand Up @@ -1363,7 +1408,8 @@ def test_update_project_member_update_error(self):
@test.create_stubs({api.keystone: ('get_default_role',
'tenant_get',
'domain_get'),
quotas: ('get_tenant_quota_data',)})
quotas: ('get_tenant_quota_data',
'get_disabled_quotas')})
def test_update_project_when_default_role_does_not_exist(self):
project = self.tenants.first()
domain_id = project.domain_id
Expand All @@ -1376,6 +1422,8 @@ def test_update_project_when_default_role_does_not_exist(self):
.AndReturn(project)
api.keystone.domain_get(IsA(http.HttpRequest), domain_id) \
.AndReturn(self.domain)
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
.AndReturn(self.disabled_quotas.first())
quotas.get_tenant_quota_data(IsA(http.HttpRequest),
tenant_id=self.tenant.id) \
.AndReturn(quota)
Expand Down
4 changes: 4 additions & 0 deletions openstack_dashboard/dashboards/admin/projects/workflows.py
Expand Up @@ -64,6 +64,10 @@ class UpdateProjectQuotaAction(workflows.Action):
label=_("Security Group Rules"))

# Neutron
security_group = forms.IntegerField(min_value=-1,
label=_("Security Groups"))
security_group_rule = forms.IntegerField(min_value=-1,
label=_("Security Group Rules"))
floatingip = forms.IntegerField(min_value=-1, label=_("Floating IPs"))
network = forms.IntegerField(min_value=-1, label=_("Networks"))
port = forms.IntegerField(min_value=-1, label=_("Ports"))
Expand Down
Expand Up @@ -202,6 +202,8 @@ def test_correct_quotas_displayed(self):
.AndReturn(self.snapshots.list())
api.cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \
.AndReturn(self.cinder_quotas.first())
api.neutron.is_extension_supported(
IsA(http.HttpRequest), 'security-group').AndReturn(True)
api.neutron.is_extension_supported(IsA(http.HttpRequest), 'quotas') \
.AndReturn(True)
api.neutron.tenant_quota_get(IsA(http.HttpRequest), self.tenant.id) \
Expand Down
6 changes: 6 additions & 0 deletions openstack_dashboard/test/test_data/nova_data.py
Expand Up @@ -159,6 +159,7 @@ def data(TEST):
TEST.volumes = utils.TestDataContainer()
TEST.quotas = utils.TestDataContainer()
TEST.quota_usages = utils.TestDataContainer()
TEST.disabled_quotas = utils.TestDataContainer()
TEST.floating_ips = utils.TestDataContainer()
TEST.floating_ips_uuid = utils.TestDataContainer()
TEST.usages = utils.TestDataContainer()
Expand Down Expand Up @@ -362,6 +363,11 @@ def get_id(is_uuid):
TEST.quotas.nova = base.QuotaSet(quota)
TEST.quotas.add(base.QuotaSet(quota))

# nova quotas disabled when neutron is enabled
disabled_quotas_nova = ['floating_ips', 'fixed_ips',
'security_groups', 'security_group_rules']
TEST.disabled_quotas.add(disabled_quotas_nova)

# Quota Usages
quota_usage_data = {'gigabytes': {'used': 0,
'quota': 1000},
Expand Down
33 changes: 15 additions & 18 deletions openstack_dashboard/usage/quotas.py
Expand Up @@ -39,7 +39,10 @@
"subnet",
"port",
"router",
"floatingip",)
"floatingip",
"security_group",
"security_group_rule",
)

QUOTA_FIELDS = NOVA_QUOTA_FIELDS + CINDER_QUOTA_FIELDS + NEUTRON_QUOTA_FIELDS

Expand Down Expand Up @@ -106,23 +109,10 @@ def _get_quota_data(request, method_name, disabled_quotas=None,


def get_default_quota_data(request, disabled_quotas=None, tenant_id=None):
qs = _get_quota_data(request,
"default_quota_get",
disabled_quotas=disabled_quotas,
tenant_id=tenant_id)

# Remove quotas information for resources provided by Neutron.
# TODO(amotoki): There is no API to get the default system quotas
# in Neutron (cf. LP#1204956), so we need to remove such quotas
# information from quotas set.
# This should be handled in _get_quota_data() eventually.
if base.is_service_enabled(request, 'network'):
if neutron.is_security_group_extension_supported(request):
sg_fields = ['security_groups', 'security_group_rules']
qs = [quota for quota in qs
if quota.name not in sg_fields]

return qs
return _get_quota_data(request,
"default_quota_get",
disabled_quotas=disabled_quotas,
tenant_id=tenant_id)


def get_tenant_quota_data(request, disabled_quotas=None, tenant_id=None):
Expand Down Expand Up @@ -164,6 +154,13 @@ def get_disabled_quotas(request):
# Remove the nova network quotas
disabled_quotas.extend(['floating_ips', 'fixed_ips'])

if neutron.is_security_group_extension_supported(request):
# If Neutron security group is supported, disable Nova quotas
disabled_quotas.extend(['security_groups', 'security_group_rules'])
else:
# If Nova security group is used, disable Neutron quotas
disabled_quotas.extend(['security_group', 'security_group_rule'])

try:
if not neutron.is_quotas_extension_supported(request):
disabled_quotas.extend(NEUTRON_QUOTA_FIELDS)
Expand Down

0 comments on commit 27873f7

Please sign in to comment.