Files
python-manilaclient/manilaclient/osc/v2/quotas.py
Stephen Finucane 3e3b385c8c Re-enable E501 errors
Change-Id: Id6ca5075bd11765f00b62b44f91635ef68205175
Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
2025-10-31 14:06:12 +00:00

471 lines
16 KiB
Python

# 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 osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
from manilaclient import api_versions
from manilaclient.common._i18n import _
class QuotaSet(command.Command):
"""Set quotas for a project or project/user or project/share-type.
It can be used to set the default class for all projects.
"""
_description = _(
"Set Quota for a project, or project/user or "
"project/share-type or a class."
)
def get_parser(self, prog_name):
parser = super().get_parser(prog_name)
quota_type = parser.add_mutually_exclusive_group()
parser.add_argument(
'project',
metavar='<project/class>',
help=_("A project (name/ID) or a class (e.g.: default)."),
)
quota_type.add_argument(
'--class',
dest='quota_class',
action='store_true',
default=False,
help=_(
"Update class quota to all projects. "
"Mutually exclusive with '--user' and '--share-type'."
),
)
quota_type.add_argument(
'--user',
metavar='<user>',
default=None,
help=_(
"Name or ID of a user to set the quotas for. "
"Mutually exclusive with '--share-type' and '--class'."
),
)
quota_type.add_argument(
'--share-type',
metavar='<share-type>',
type=str,
default=None,
help=_(
"Name or ID of a share type to set the quotas for. "
"Mutually exclusive with '--user' and '--class'. "
"Available only for microversion >= 2.39"
),
)
parser.add_argument(
'--shares',
metavar='<shares>',
type=int,
default=None,
help=_('New value for the "shares" quota.'),
)
parser.add_argument(
'--snapshots',
metavar='<snapshots>',
type=int,
default=None,
help=_('New value for the "snapshots" quota.'),
)
parser.add_argument(
'--gigabytes',
metavar='<gigabytes>',
type=int,
default=None,
help=_('New value for the "gigabytes" quota.'),
)
parser.add_argument(
'--snapshot-gigabytes',
metavar='<snapshot-gigabytes>',
type=int,
default=None,
help=_('New value for the "snapshot-gigabytes" quota.'),
)
parser.add_argument(
'--share-networks',
metavar='<share-networks>',
type=int,
default=None,
help=_('New value for the "share-networks" quota.'),
)
parser.add_argument(
'--share-groups',
metavar='<share-groups>',
type=int,
default=None,
help=_(
'New value for the "share-groups" quota. '
'Available only for microversion >= 2.40'
),
)
parser.add_argument(
'--share-group-snapshots',
metavar='<share-group-snapshots>',
type=int,
default=None,
help=_(
'New value for the "share-group-snapshots" quota. '
'Available only for microversion >= 2.40'
),
)
parser.add_argument(
'--share-replicas',
metavar='<share-replicas>',
type=int,
default=None,
help=_(
"Number of share replicas. "
"Available only for microversion >= 2.53"
),
)
parser.add_argument(
'--replica-gigabytes',
metavar='<replica-gigabytes>',
type=int,
default=None,
help=_(
"Capacity of share replicas in total. "
"Available only for microversion >= 2.53"
),
)
parser.add_argument(
'--per-share-gigabytes',
metavar='<per-share-gigabytes>',
type=int,
default=None,
help=_(
'New value for the "per-share-gigabytes" quota. '
'Available only for microversion >= 2.62'
),
)
parser.add_argument(
'--encryption-keys',
metavar='<encryption-keys>',
type=int,
default=None,
help=_(
'New value for the "encryption-keys" quota. '
'Available only for microversion >= 2.90'
),
)
parser.add_argument(
'--force',
dest='force',
action="store_true",
default=None,
help=_('Force update the quota. Not applicable for class update.'),
)
return parser
def take_action(self, parsed_args):
share_client = self.app.client_manager.share
identity_client = self.app.client_manager.identity
user_id = None
if parsed_args.user:
user_id = utils.find_resource(
identity_client.users, parsed_args.user
).id
kwargs = {
"shares": parsed_args.shares,
"snapshots": parsed_args.snapshots,
"gigabytes": parsed_args.gigabytes,
"snapshot_gigabytes": parsed_args.snapshot_gigabytes,
"share_networks": parsed_args.share_networks,
}
if parsed_args.share_type is not None:
if share_client.api_version < api_versions.APIVersion('2.39'):
raise exceptions.CommandError(
_(
"'share type' quotas are available only starting with "
"'2.39' API microversion."
)
)
kwargs["share_type"] = parsed_args.share_type
if parsed_args.share_groups is not None:
if share_client.api_version < api_versions.APIVersion('2.40'):
raise exceptions.CommandError(
_(
"'share group' quotas are available only "
"starting with '2.40' API microversion."
)
)
kwargs["share_groups"] = parsed_args.share_groups
if parsed_args.share_group_snapshots is not None:
if share_client.api_version < api_versions.APIVersion('2.40'):
raise exceptions.CommandError(
_(
"'share group snapshots' quotas are available only "
"starting with '2.40' API microversion."
)
)
kwargs["share_group_snapshots"] = parsed_args.share_group_snapshots
if parsed_args.share_replicas is not None:
if share_client.api_version < api_versions.APIVersion('2.53'):
raise exceptions.CommandError(
_(
"setting the number of 'share replicas' is available "
"only starting with API microversion '2.53'."
)
)
kwargs["share_replicas"] = parsed_args.share_replicas
if parsed_args.replica_gigabytes is not None:
if share_client.api_version < api_versions.APIVersion('2.53'):
raise exceptions.CommandError(
_(
"setting the capacity of share replicas in total "
"is available only starting with API microversion "
"'2.53'."
)
)
kwargs["replica_gigabytes"] = parsed_args.replica_gigabytes
if parsed_args.per_share_gigabytes is not None:
if share_client.api_version < api_versions.APIVersion('2.62'):
raise exceptions.CommandError(
_(
"'per share gigabytes' quotas are available only "
"starting with '2.62' API microversion."
)
)
kwargs["per_share_gigabytes"] = parsed_args.per_share_gigabytes
if parsed_args.encryption_keys is not None:
if share_client.api_version < api_versions.APIVersion('2.90'):
raise exceptions.CommandError(
_(
"'encryption keys' quotas are available only "
"starting with '2.90' API microversion."
)
)
kwargs["encryption_keys"] = parsed_args.encryption_keys
if all(value is None for value in kwargs.values()):
raise exceptions.CommandError(
_(
"Nothing to set. "
"New quota must be specified to at least one of the "
"following resources: 'shares', 'snapshots', 'gigabytes', "
"'snapshot-gigabytes', 'share-networks', 'share-type', "
"'share-groups', 'share-group-snapshots', "
"'share-replicas', 'replica-gigabytes', "
"'per-share-gigabytes', 'encryption_keys'"
)
)
if parsed_args.quota_class:
kwargs.update(
{
"class_name": parsed_args.project,
}
)
try:
share_client.quota_classes.update(**kwargs)
except Exception as e:
msg = _(
"Failed to set quotas for class '%(project)s': '%(e)s'"
)
raise exceptions.CommandError(
msg % {'project': parsed_args.project, 'e': e}
)
else:
project_id = utils.find_resource(
identity_client.projects, parsed_args.project
).id
kwargs.update(
{
"tenant_id": project_id,
"force": parsed_args.force,
"user_id": user_id,
}
)
try:
share_client.quotas.update(**kwargs)
except Exception as e:
msg = _(
"Failed to set quotas for project '%(project)s': '%(e)s'"
)
raise exceptions.CommandError(
msg % {'project': parsed_args.project, 'e': e}
)
class QuotaShow(command.ShowOne):
"""List the quotas for a project or project/user or project/share-type."""
_description = _("Show Quota")
def get_parser(self, prog_name):
parser = super().get_parser(prog_name)
quota_type = parser.add_mutually_exclusive_group()
parser.add_argument(
'project',
metavar='<project>',
help=_('Name or ID of the project to list quotas for.'),
)
quota_type.add_argument(
'--user',
metavar='<user>',
default=None,
help=_(
"Name or ID of user to list the quotas for. Optional. "
"Mutually exclusive with '--share-type'."
),
)
quota_type.add_argument(
'--share-type',
metavar='<share-type>',
type=str,
default=None,
help=_(
"Name or ID of a share type to list the quotas for. "
"Optional. "
"Mutually exclusive with '--user'. "
"Available only for microversion >= 2.39"
),
)
parser.add_argument(
'--detail',
action='store_true',
default=False,
help=_(
'Optional flag to indicate whether to show quota in detail.'
' Default false, available only for microversion >= 2.25.'
),
)
parser.add_argument(
'--defaults',
action='store_true',
default=False,
help=_('Show the default quotas for the project.'),
)
return parser
def take_action(self, parsed_args):
share_client = self.app.client_manager.share
identity_client = self.app.client_manager.identity
user_id = None
if parsed_args.user:
user_id = utils.find_resource(
identity_client.users, parsed_args.user
).id
project_id = utils.find_resource(
identity_client.projects, parsed_args.project
).id
quotas = {}
if parsed_args.defaults:
quotas = share_client.quotas.defaults(project_id)
else:
kwargs = {
"tenant_id": project_id,
"user_id": user_id,
"detail": parsed_args.detail,
}
if parsed_args.share_type is not None:
if share_client.api_version < api_versions.APIVersion("2.39"):
raise exceptions.CommandError(
_(
"'share type' quotas are available only "
"starting with '2.39' API microversion."
)
)
kwargs["share_type"] = parsed_args.share_type
quotas = share_client.quotas.get(**kwargs)
printable_quotas = {}
for quota_k, quota_v in sorted(quotas.to_dict().items()):
if isinstance(quota_v, dict):
quota_v = '\n'.join(
[f'{k} = {v}' for k, v in sorted(quota_v.items())]
)
printable_quotas[quota_k] = quota_v
return self.dict2columns(printable_quotas)
class QuotaDelete(command.Command):
"""Delete quota for project/user or project/share-type.
The quota will revert back to default.
"""
_description = _("Delete Quota")
def get_parser(self, prog_name):
parser = super().get_parser(prog_name)
quota_type = parser.add_mutually_exclusive_group()
parser.add_argument(
'project',
metavar='<project>',
help=_('Name or ID of the project to delete quotas for.'),
)
quota_type.add_argument(
'--user',
metavar='<user>',
default=None,
help=_(
"Name or ID of user to delete the quotas for. Optional. "
"Mutually exclusive with '--share-type'."
),
)
quota_type.add_argument(
'--share-type',
metavar='<share-type>',
type=str,
default=None,
help=_(
"Name or ID of a share type to delete the quotas for. "
"Optional. "
"Mutually exclusive with '--user'. "
"Available only for microversion >= 2.39"
),
)
return parser
def take_action(self, parsed_args):
share_client = self.app.client_manager.share
identity_client = self.app.client_manager.identity
user_id = None
if parsed_args.user:
user_id = utils.find_resource(
identity_client.users, parsed_args.user
).id
project_id = utils.find_resource(
identity_client.projects, parsed_args.project
).id
kwargs = {"tenant_id": project_id, "user_id": user_id}
if parsed_args.share_type:
if share_client.api_version < api_versions.APIVersion("2.39"):
raise exceptions.CommandError(
_(
"'share type' quotas are available only starting with "
"API microversion '2.39'."
)
)
kwargs["share_type"] = parsed_args.share_type
share_client.quotas.delete(**kwargs)