diff --git a/manila_ui/api/manila.py b/manila_ui/api/manila.py index 0d9a533a..93231576 100644 --- a/manila_ui/api/manila.py +++ b/manila_ui/api/manila.py @@ -39,6 +39,14 @@ MANILA_SERVICE_TYPE = "sharev2" SHARE_STATE_AVAILABLE = "available" DEFAULT_QUOTA_NAME = 'default' +MANILA_QUOTA_FIELDS = { + "shares", + "share_gigabytes", + "share_snapshots", + "share_snapshot_gigabytes", + "share_networks", +} + def manilaclient(request): insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False) diff --git a/manila_ui/dashboards/admin/defaults/__init__.py b/manila_ui/dashboards/admin/defaults/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/manila_ui/dashboards/admin/defaults/tables.py b/manila_ui/dashboards/admin/defaults/tables.py new file mode 100644 index 00000000..bcc7a9fb --- /dev/null +++ b/manila_ui/dashboards/admin/defaults/tables.py @@ -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. + +from django.utils.translation import ugettext_lazy as _ + +from horizon import tables + +from openstack_dashboard.dashboards.admin.defaults import tables as default_tbl + + +MANILA_QUOTA_NAMES = { + 'shares': _('Shares'), + 'gigabytes': _('Share gigabytes'), + 'snapshots': _('Share snapshots'), + 'snapshot_gigabytes': _('Share snapshot gigabytes'), + 'share_networks': _('Shares Networks'), +} + + +def get_quota_name(quota): + return MANILA_QUOTA_NAMES.get(quota.name, + quota.name.replace("_", " ").title()) + + +class UpdateDefaultShareQuotas(default_tbl.UpdateDefaultQuotas): + name = 'update_share_defaults' + step = 'update_default_share_quotas' + + +class ShareQuotasTable(tables.DataTable): + name = tables.Column(get_quota_name, verbose_name=_('Quota Name')) + limit = tables.Column("limit", verbose_name=_('Limit')) + + def get_object_id(self, obj): + return obj.name + + class Meta(object): + name = "share_quotas" + verbose_name = _("Shared Quotas") + table_actions = (default_tbl.QuotaFilterAction, + UpdateDefaultShareQuotas) + multi_select = False diff --git a/manila_ui/dashboards/admin/defaults/tabs.py b/manila_ui/dashboards/admin/defaults/tabs.py new file mode 100644 index 00000000..4692af44 --- /dev/null +++ b/manila_ui/dashboards/admin/defaults/tabs.py @@ -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. + +from django.utils.translation import ugettext_lazy as _ + +from horizon import exceptions +from horizon import tabs + +from openstack_dashboard import api + +from manila_ui.api import manila as api_manila +from manila_ui.dashboards.admin.defaults import tables + + +class ShareQuotasTab(tabs.TableTab): + table_classes = (tables.ShareQuotasTable,) + name = _("Share Quotas") + slug = "shared_quotas" + template_name = ("horizon/common/_detail_table.html") + + def get_share_quotas_data(self): + request = self.tab_group.request + tenant_id = request.user.tenant_id + try: + data = api_manila.default_quota_get(request, tenant_id) + except Exception: + data = [] + exceptions.handle(self.request, + _('Unable to get manila default quota.')) + return data + + def allowed(self, request): + return api.base.is_service_enabled(request, 'share') diff --git a/manila_ui/dashboards/admin/defaults/workflows.py b/manila_ui/dashboards/admin/defaults/workflows.py new file mode 100644 index 00000000..7f930d1e --- /dev/null +++ b/manila_ui/dashboards/admin/defaults/workflows.py @@ -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. + +from django.utils.translation import ugettext_lazy as _ + +from horizon import exceptions +from horizon import forms +from horizon import workflows + +from openstack_dashboard.api import base + +from manila_ui.api import manila as api_manila + + +class UpdateDefaultShareQuotasAction(workflows.Action): + shares = forms.IntegerField(min_value=-1, label=_("Shares")) + share_gigabytes = forms.IntegerField( + min_value=-1, label=_("Share gigabytes")) + share_snapshots = forms.IntegerField( + min_value=-1, label=_("Share snapshots")) + share_snapshot_gigabytes = forms.IntegerField( + min_value=-1, label=_("Share snapshot gigabytes")) + share_networks = forms.IntegerField( + min_value=-1, label=_("Share Networks")) + + def __init__(self, request, context, *args, **kwargs): + super(UpdateDefaultShareQuotasAction, self).__init__( + request, context, *args, **kwargs) + disabled_quotas = context['disabled_quotas'] + for field in disabled_quotas: + if field in self.fields: + self.fields[field].required = False + self.fields[field].widget = forms.HiddenInput() + + def handle(self, request, data): + try: + if base.is_service_enabled(request, 'share'): + manila_data = dict([(key, data[key]) for key in + api_manila.MANILA_QUOTA_FIELDS]) + api_manila.default_quota_update(request, **manila_data) + return True + except Exception: + exceptions.handle(request, + _('Unable to update default quotas.')) + return False + + class Meta(object): + name = _("Share") + slug = 'update_default_share_quotas' + help_text = _("From here you can update the default share quotas " + "(max limits).") + + +class UpdateDefaultShareQuotasStep(workflows.Step): + action_class = UpdateDefaultShareQuotasAction + contributes = api_manila.MANILA_QUOTA_FIELDS + depends_on = ('disabled_quotas',) + + def prepare_action_context(self, request, context): + try: + quota_defaults = api_manila.default_quota_get( + request, request.user.tenant_id) + for field in api_manila.MANILA_QUOTA_FIELDS: + context[field] = quota_defaults.get(field).limit + except Exception: + exceptions.handle(request, + _('Unable to retrieve default share quotas.')) + return context + + def allowed(self, request): + return base.is_service_enabled(request, 'share') diff --git a/manila_ui/dashboards/identity/__init__.py b/manila_ui/dashboards/identity/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/manila_ui/dashboards/identity/projects/__init__.py b/manila_ui/dashboards/identity/projects/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/manila_ui/dashboards/identity/projects/workflows.py b/manila_ui/dashboards/identity/projects/workflows.py new file mode 100644 index 00000000..82450026 --- /dev/null +++ b/manila_ui/dashboards/identity/projects/workflows.py @@ -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. + +from django.utils.translation import ugettext_lazy as _ + +from horizon import forms +from horizon import workflows + +from openstack_dashboard.api import base +from openstack_dashboard.dashboards.identity.projects \ + import workflows as project_workflows + +from manila_ui.api import manila as api_manila + + +class ShareQuotaAction(project_workflows.CommonQuotaAction): + shares = forms.IntegerField(min_value=-1, label=_("Shares")) + share_gigabytes = forms.IntegerField( + min_value=-1, label=_("Share gigabytes")) + share_snapshots = forms.IntegerField( + min_value=-1, label=_("Share snapshots")) + share_snapshot_gigabytes = forms.IntegerField( + min_value=-1, label=_("Share snapshot gigabytes")) + share_networks = forms.IntegerField( + min_value=-1, label=_("Share Networks")) + + _quota_fields = api_manila.MANILA_QUOTA_FIELDS + + def _tenant_quota_update(self, request, project_id, data): + api_manila.tenant_quota_update(request, project_id, **data) + + class Meta(object): + name = _("Share") + slug = 'update_share_quotas' + help_text = _("Set maximum quotas for the project.") + permissions = ('openstack.roles.admin', 'openstack.services.share') + + +class UpdateShareQuota(workflows.Step): + action_class = ShareQuotaAction + depends_on = ("project_id", "disabled_quotas") + contributes = api_manila.MANILA_QUOTA_FIELDS + + def allowed(self, request): + return base.is_service_enabled(request, 'share') diff --git a/manila_ui/dashboards/project/shares/__init__.py b/manila_ui/dashboards/project/shares/__init__.py index 3a04dc2f..e8889a53 100644 --- a/manila_ui/dashboards/project/shares/__init__.py +++ b/manila_ui/dashboards/project/shares/__init__.py @@ -10,343 +10,21 @@ # License for the specific language governing permissions and limitations # under the License. -import functools -import sys - from django.utils.translation import ugettext_lazy as _ -import horizon +from horizon import exceptions + +from openstack_dashboard.api import base +from openstack_dashboard.usage import base as usage from manila_ui.api import manila -from openstack_dashboard.api import base -from openstack_dashboard.dashboards.admin.defaults import tables as quota_tbl -from openstack_dashboard.dashboards.admin.defaults import views \ - as default_views -from openstack_dashboard.dashboards.admin.defaults import workflows \ - as default_workflows -from openstack_dashboard.dashboards.identity.projects import views \ - as project_views -from openstack_dashboard.dashboards.identity.projects import workflows \ - as project_workflows -from openstack_dashboard.dashboards.project.overview import views \ - as overview_views -from openstack_dashboard.usage import base as usage_base -from openstack_dashboard.usage import quotas - - -def wrap(orig_func): - """decorator to wrap an existing function - Modified post from http://downgra.de/2009/05/16/python-monkey-patching/ - to work with functions - e.g. - - @wrap(quotas.tenant_limit_usages) - def tenant_limit_usages(orig, self): - limits = orig(request) - limits['disksUsed'] = 100 - return limits - - the first parameter of the new function is the the original, - overwritten function ('orig'). - """ - - def outer(new_func): - @functools.wraps(orig_func) - def wrapper(*args, **kwargs): - return new_func(orig_func, *args, **kwargs) - # Replace the original function in the module with the wrapper - orig_module = sys.modules[orig_func.__module__] - setattr(orig_module, orig_func.__name__, wrapper) - return wrapper - return outer - - -# All public methods in openstack_dashboard.usage.quotas are hardcoded to -# only look at a fixed set of services (nova, cinder, etc.). In order to -# incorporate manila quotas and usage, all public functions must be -# monkey-patched to add that information in. - -MANILA_QUOTA_FIELDS = { - "shares", - "share_gigabytes", - "share_snapshots", - "share_snapshot_gigabytes", - "share_networks", -} -MANILA_QUOTA_NAMES = { - 'shares': _('Shares'), - 'share_gigabytes': _('Share gigabytes'), - 'share_snapshots': _('Share snapshots'), - 'share_snapshot_gigabytes': _('Share snapshot gigabytes'), - 'share_networks': _('Shares Networks'), -} - -quotas.QUOTA_FIELDS = quotas.QUOTA_FIELDS | MANILA_QUOTA_FIELDS - - -def _get_manila_disabled_quotas(request): - disabled_quotas = [] - if not base.is_service_enabled(request, 'share'): - disabled_quotas.extend(MANILA_QUOTA_FIELDS) - - return disabled_quotas - - -def _get_manila_quota_data(request, method_name, disabled_quotas=None, - tenant_id=None): - if not tenant_id: - tenant_id = request.user.tenant_id - if disabled_quotas is None: - disabled_quotas = _get_manila_disabled_quotas(request) - if 'shares' not in disabled_quotas: - manila_quotas = getattr(manila, method_name)(request, tenant_id) - for quota in manila_quotas: - if quota.name == 'gigabytes': - quota.name = 'share_gigabytes' - elif quota.name == 'snapshots': - quota.name = 'share_snapshots' - elif quota.name == 'snapshot_gigabytes': - quota.name = 'share_snapshot_gigabytes' - return manila_quotas - else: - return None - - -@wrap(quotas.get_default_quota_data) -def get_default_quota_data(f, request, disabled_quotas=None, tenant_id=None): - qs = f(request, disabled_quotas, tenant_id) - manila_quota = _get_manila_quota_data(request, "default_quota_get", - disabled_quotas=disabled_quotas, - tenant_id=tenant_id) - if manila_quota: - qs.add(manila_quota) - return qs - - -@wrap(quotas.get_tenant_quota_data) -def get_tenant_quota_data(f, request, disabled_quotas=None, tenant_id=None): - qs = f(request, disabled_quotas, tenant_id) - manila_quota = _get_manila_quota_data(request, "tenant_quota_get", - disabled_quotas=disabled_quotas, - tenant_id=tenant_id) - if manila_quota: - qs.add(manila_quota) - return qs - - -@wrap(quotas.get_disabled_quotas) -def get_disabled_quotas(f, request): - disabled_quotas = f(request) - disabled_quotas.update(_get_manila_disabled_quotas(request)) - return disabled_quotas - - -@wrap(quotas.tenant_quota_usages) -def tenant_quota_usages(f, request, tenant_id=None, targets=None): - - usages = f(request, tenant_id, targets) - - if 'shares' not in _get_manila_disabled_quotas(request): - shares = manila.share_list(request) - snapshots = manila.share_snapshot_list(request) - sn_l = manila.share_network_list(request) - gig_s = sum([int(v.size) for v in shares]) - gig_ss = sum([int(v.size) for v in snapshots]) - usages.tally('shares', len(shares)) - usages.tally('share_gigabytes', gig_s) - usages.tally('share_snapshots', len(snapshots)) - usages.tally('share_snapshot_gigabytes', gig_ss) - usages.tally('share_networks', len(sn_l)) - - return usages - - -@wrap(quotas.tenant_limit_usages) -def tenant_limit_usages(f, request): - - limits = f(request) - - if base.is_service_enabled(request, 'share'): - try: - limits.update(manila.tenant_absolute_limits(request)) - shares = manila.share_list(request) - snapshots = manila.share_snapshot_list(request) - share_networks = manila.share_network_list(request) - total_s_size = sum([getattr(share, 'size', 0) for share in shares]) - total_ss_size = sum([getattr(ss, 'size', 0) for ss in snapshots]) - limits['totalSharesUsed'] = len(shares) - limits['totalShareGigabytesUsed'] = total_s_size - limits['totalSnapshotsUsed'] = len(snapshots) - limits['totalSnapshotGigabytesUsed'] = total_ss_size - limits['totalShareNetworksUsed'] = len(share_networks) - except Exception: - msg = _("Unable to retrieve share limit information.") - horizon.exceptions.handle(request, msg) - - return limits - - -@wrap(quota_tbl.get_quota_name) -def get_quota_name(f, quota): - if quota.name in MANILA_QUOTA_NAMES: - return MANILA_QUOTA_NAMES.get(quota.name) - else: - return f(quota) - - # -# Add manila fields to Admin/Defaults/Update Defaults +# Add extra pie charts to project/compute overview # -class ManilaUpdateDefaultQuotaAction( - default_workflows.UpdateDefaultQuotasAction): - shares = horizon.forms.IntegerField(min_value=-1, label=_("Shares")) - share_gigabytes = horizon.forms.IntegerField( - min_value=-1, label=_("Share gigabytes")) - share_snapshots = horizon.forms.IntegerField( - min_value=-1, label=_("Share snapshots")) - share_snapshot_gigabytes = horizon.forms.IntegerField( - min_value=-1, label=_("Share snapshot gigabytes")) - share_networks = horizon.forms.IntegerField( - min_value=-1, label=_("Share Networks")) - - class Meta(object): - name = _("Default Quotas") - slug = 'update_default_quotas' - help_text = _("From here you can update the default quotas " - "(max limits).") - - -class ManilaUpdateDefaultQuotasStep(default_workflows.UpdateDefaultQuotasStep): - action_class = ManilaUpdateDefaultQuotaAction - contributes = quotas.QUOTA_FIELDS - - -class ManilaUpdateDefaultQuotas(default_workflows.UpdateDefaultQuotas): - default_steps = (ManilaUpdateDefaultQuotasStep,) - - def handle(self, request, data): - try: - super(ManilaUpdateDefaultQuotas, self).handle(request, data) - - if base.is_service_enabled(request, 'share'): - manila_data = dict([(key, data[key]) for key in - MANILA_QUOTA_FIELDS]) - manila.default_quota_update(request, **manila_data) - - except Exception: - horizon.exceptions.handle(request, - _('Unable to update default quotas.')) - - return True - - -default_views.UpdateDefaultQuotasView.workflow_class = ( - ManilaUpdateDefaultQuotas) - -# -# Add manila fields to Identity/Projects/Modify Quotas -# - - -class ManilaUpdateProjectQuotaAction( - project_workflows.UpdateProjectQuotaAction): - shares = horizon.forms.IntegerField(min_value=-1, label=_("Shares")) - share_gigabytes = horizon.forms.IntegerField( - min_value=-1, label=_("Share gigabytes")) - share_snapshots = horizon.forms.IntegerField( - min_value=-1, label=_("Share snapshots")) - share_snapshot_gigabytes = horizon.forms.IntegerField( - min_value=-1, label=_("Share snapshot gigabytes")) - share_networks = horizon.forms.IntegerField( - min_value=-1, label=_("Share Networks")) - - class Meta(object): - name = _("Quota") - slug = 'update_quotas' - help_text = _("Set maximum quotas for the project.") - -project_workflows.UpdateProjectQuota.action_class = ( - ManilaUpdateProjectQuotaAction) -project_workflows.UpdateProjectQuota.contributes = quotas.QUOTA_FIELDS - - -class ManilaUpdateProject(project_workflows.UpdateProject): - def handle(self, request, data): - try: - super(ManilaUpdateProject, self).handle(request, data) - - if base.is_service_enabled(request, 'share'): - manila_data = dict([(key, data[key]) for key in - MANILA_QUOTA_FIELDS]) - manila.tenant_quota_update(request, - data['project_id'], - **manila_data) - - except Exception: - horizon.exceptions.handle(request, - _('Modified project information and ' - 'members, but unable to modify ' - 'project quotas.')) - return True - -project_views.UpdateProjectView.workflow_class = ManilaUpdateProject - -# -# Add manila fields to Identity/Projects/Create Project -# - - -class ManilaCreateProjectQuotaAction( - project_workflows.CreateProjectQuotaAction): - shares = horizon.forms.IntegerField(min_value=-1, label=_("Shares")) - share_gigabytes = horizon.forms.IntegerField( - min_value=-1, label=_("Share gigabytes")) - share_snapshots = horizon.forms.IntegerField( - min_value=-1, label=_("Share snapshots")) - share_snapshot_gigabytes = horizon.forms.IntegerField( - min_value=-1, label=_("Share snapshot gigabytes")) - share_networks = horizon.forms.IntegerField( - min_value=-1, label=_("Share Networks")) - - class Meta(object): - name = _("Quota") - slug = 'create_quotas' - help_text = _("Set maximum quotas for the project.") - - -project_workflows.CreateProjectQuota.action_class = ( - ManilaCreateProjectQuotaAction) -project_workflows.CreateProjectQuota.contributes = quotas.QUOTA_FIELDS - - -class ManilaCreateProject(project_workflows.CreateProject): - def handle(self, request, data): - try: - super(ManilaCreateProject, self).handle(request, data) - - if base.is_service_enabled(request, 'share'): - manila_data = dict([(key, data[key]) for key in - MANILA_QUOTA_FIELDS]) - manila.tenant_quota_update(request, - self.object.id, - **manila_data) - - except Exception: - horizon.exceptions.handle(request, - _('Unable to set project quotas.')) - return True - -project_views.CreateProjectView.workflow_class = ManilaCreateProject - -# -# Add extra pie charts to Project/Compute Overview -# - - -class ManilaUsage(usage_base.ProjectUsage): +class ManilaUsage(usage.ProjectUsage): def get_manila_limits(self): """Get share limits if manila is enabled.""" @@ -356,7 +34,7 @@ class ManilaUsage(usage_base.ProjectUsage): self.limits.update(manila.tenant_absolute_limits(self.request)) except Exception: msg = _("Unable to retrieve share limit information.") - horizon.exceptions.handle(self.request, msg) + exceptions.handle(self.request, msg) return def get_limits(self): @@ -387,7 +65,3 @@ def get_context_data(self, **kwargs): 'text': False, }) return context - - -overview_views.ProjectOverview.get_context_data = get_context_data -overview_views.ProjectOverview.usage_class = ManilaUsage diff --git a/manila_ui/local/enabled/_80_manila_admin_add_share_panel_group.py b/manila_ui/local/enabled/_80_manila_admin_add_share_panel_group.py index 90a8b980..d071d6ee 100644 --- a/manila_ui/local/enabled/_80_manila_admin_add_share_panel_group.py +++ b/manila_ui/local/enabled/_80_manila_admin_add_share_panel_group.py @@ -18,3 +18,19 @@ PANEL_GROUP = 'share' PANEL_GROUP_NAME = 'Share' # The slug of the dashboard the PANEL_GROUP associated with. Required. PANEL_GROUP_DASHBOARD = 'admin' + +EXTRA_TABS = { + 'openstack_dashboard.dashboards.admin.defaults.tabs.DefaultsTabs': ( + 'manila_ui.dashboards.admin.defaults.tabs.ShareQuotasTab', + ), +} +EXTRA_STEPS = { + 'openstack_dashboard.dashboards.identity.projects.workflows.UpdateQuota': ( + 'manila_ui.dashboards.identity.projects.workflows.UpdateShareQuota', + ), + 'openstack_dashboard.dashboards.admin.defaults.workflows.' + 'UpdateDefaultQuotas': ( + 'manila_ui.dashboards.admin.defaults.workflows.' + 'UpdateDefaultShareQuotasStep', + ), +} diff --git a/manila_ui/tests/dashboards/project/tests.py b/manila_ui/tests/dashboards/project/tests.py index 626333d8..9926595e 100644 --- a/manila_ui/tests/dashboards/project/tests.py +++ b/manila_ui/tests/dashboards/project/tests.py @@ -12,14 +12,10 @@ # License for the specific language governing permissions and limitations # under the License. -import ddt from django.core.urlresolvers import reverse from django.utils import translation import mock -from openstack_dashboard.api import base -from openstack_dashboard.usage import quotas -from manila_ui.api import manila as api_manila from manila_ui.dashboards.project import shares from manila_ui.tests import helpers as test @@ -85,80 +81,3 @@ class PieChartsTests(test.TestCase): "text": chart["text"]}, expected_charts.pop(name, "NotFound") ) - - -@ddt.ddt -class QuotaTests(test.TestCase): - - def test_get_disabled_quotas(self): - self.mock_object( - base, "is_service_enabled", mock.Mock(return_value=False)) - - result_quotas = quotas.get_disabled_quotas(self.request) - - expected_quotas = set(quotas.QUOTA_FIELDS) - self.assertItemsEqual(result_quotas, expected_quotas) - - @ddt.data( - shares.ManilaUpdateDefaultQuotaAction, - shares.ManilaUpdateProjectQuotaAction, - shares.ManilaCreateProjectQuotaAction, - ) - def test_manila_quota_action(self, class_ref): - self.mock_object( - quotas, 'get_disabled_quotas', mock.Mock(return_value=[])) - class_instance = class_ref(self.request, 'foo') - expected_fields = set([ - 'shares', 'share_gigabytes', 'share_snapshots', - 'share_snapshot_gigabytes', 'share_networks', - ]) - # NOTE(vponomaryov): iterate over reversed list of visible fields - # because manila's fields are at the end always. - for vf in reversed(class_instance.visible_fields()): - if expected_fields and vf.name in expected_fields: - self.assertEqual(-1, vf.field.min_value) - self.assertIsInstance( - vf.field, shares.horizon.forms.IntegerField) - expected_fields.remove(vf.name) - self.assertSetEqual(set([]), expected_fields) - self.assertTrue(quotas.get_disabled_quotas.called) - - @ddt.data('default_quota_get', 'tenant_quota_get') - def test__get_manila_quota_data(self, method_name): - fake_quotas = [ - type('Fake', (object, ), {'name': name}) - for name in ('gigabytes', 'snapshots', 'snapshot_gigabytes') - ] - self.mock_object( - api_manila, method_name, mock.Mock(return_value=fake_quotas)) - self.mock_object( - shares, '_get_manila_disabled_quotas', - mock.Mock(return_value=[])) - - result = shares._get_manila_quota_data( - self.request, method_name) - - expected = [ - 'share_gigabytes', - 'share_snapshot_gigabytes', - 'share_snapshots', - ] - self.assertEqual(3, len(result)) - self.assertEqual( - expected, - sorted([element.name for element in result])) - getattr(api_manila, method_name).assert_called_once_with( - self.request, self.request.user.tenant_id) - shares._get_manila_disabled_quotas.asssert_called_once_with( - self.request) - - def test_manila_quota_fields(self): - expected_fields = ( - "shares", - "share_gigabytes", - "share_snapshots", - "share_snapshot_gigabytes", - "share_networks", - ) - for ef in expected_fields: - self.assertIn(ef, shares.quotas.QUOTA_FIELDS)