[OSC] Implement Share Limits Show command

Adding the following openstack command,
share limits show --absolute
share limits show --rate

Partially-implements: bp openstack-client-support
Co-Authored-By: Goutham Pacha Ravi <gouthampravi@gmail.com>
Change-Id: I68b98a6c3ee369be1422d2f45e75d034e68da2e0
This commit is contained in:
Vida Haririan 2021-08-25 08:19:53 -04:00
parent 2f173cb150
commit cc440609bd
7 changed files with 253 additions and 0 deletions

View File

@ -123,3 +123,10 @@ share pools
.. autoprogram-cliff:: openstack.share.v2
:command: share pool list
============
share limits
============
.. autoprogram-cliff:: openstack.share.v2
:command: share limits *

View File

@ -0,0 +1,74 @@
# Copyright 2021 Red Hat, Inc.
#
# 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.
import logging
from osc_lib.command import command
from osc_lib import utils as oscutils
from manilaclient.common._i18n import _
LOG = logging.getLogger(__name__)
class ShareLimitsShow(command.Lister):
"""Show a list of share limits for a user."""
_description = _("Show a list of share limits for a user.")
def get_parser(self, prog_name):
parser = super(ShareLimitsShow, self).get_parser(prog_name)
limit_type_group = parser.add_mutually_exclusive_group(required=True)
limit_type_group.add_argument(
'--absolute',
action='store_true',
default=False,
help=_('Get the absolute limits for the user')
)
limit_type_group.add_argument(
'--rate',
action='store_true',
default=False,
help=_('Get the API rate limits for the user')
)
return parser
def take_action(self, parsed_args):
share_client = self.app.client_manager.share
# limit_type = 'absolute'
if parsed_args.rate:
# limit_type = 'rate'
columns = [
"Verb",
"Regex",
"URI",
"Value",
"Remaining",
"Unit",
"Next Available",
]
data = list(share_client.limits.get().rate)
else:
columns = [
'Name',
'Value',
]
data = list(share_client.limits.get().absolute)
return (columns, (oscutils.get_item_properties(s, columns)
for s in data))

View File

@ -198,3 +198,43 @@ class FakeResource(object):
def get(self, item, default=None):
return self._info.get(item, default)
class FakeLimitsResource(FakeResource):
class AbsoluteLimit:
def __init__(self, name, value):
self.name = name
self.value = value
class RateLimit:
def __init__(self, verb, uri, regex, value, remaining,
unit, next_available):
self.verb = verb
self.uri = uri
self.regex = regex
self.value = value
self.remaining = remaining
self.unit = unit
self.next_available = next_available
@property
def absolute(self):
return [
self.AbsoluteLimit(key, value)
for key, value in self._info['absolute_limit'].items()
]
@property
def rate(self):
rate = self._info['rate_limit']
return [
self.RateLimit(
rate['verb'],
rate['uri'],
rate['regex'],
rate['value'],
rate['remaining'],
rate['unit'],
rate['next-available'])
]

View File

@ -50,6 +50,7 @@ class FakeShareClient(object):
self.services = mock.Mock()
self.share_instances = mock.Mock()
self.pools = mock.Mock()
self.limits = mock.Mock()
class ManilaParseException(Exception):
@ -963,3 +964,39 @@ class FakeShareInstance(object):
share_instances.append(
FakeShareInstance.create_one_share_instance(attrs))
return share_instances
class FakeShareLimits(object):
"""Fake one or more share limits"""
@staticmethod
def create_one_share_limit(attrs=None):
"""Create a fake share limit dict
:param Dictionary attrs:
A dictionary with all attributes
:return:
A FakeLimitsResource object, with share limits.
"""
attrs = attrs or {}
share_limits = {
'absolute_limit': {
"totalShareNetworksUsed": 4,
},
'rate_limit': {
"regex": "^/shares",
"uri": "/shares",
"verb": "GET",
"next-available": "2021-09-01T00:00:00Z",
"unit": "MINUTE",
"value": "3",
"remaining": "1",
}
}
share_limits.update(attrs)
share_limits = osc_fakes.FakeLimitsResource(
info=copy.deepcopy(share_limits), loaded=True)
return share_limits

View File

@ -0,0 +1,93 @@
# Copyright 2021 Red Hat Inc. All rights reserved.
#
# 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.
#
import ddt
from manilaclient import api_versions
from manilaclient.api_versions import MAX_VERSION
from manilaclient.osc.v2 import share_limits as osc_share_limits
from manilaclient.tests.unit.osc.v2 import fakes as manila_fakes
class TestShareLimits(manila_fakes.TestShare):
def setUp(self):
super(TestShareLimits, self).setUp()
self.share_limits_mock = self.app.client_manager.share.limits
self.share_limits_mock.reset_mock()
self.app.client_manager.share.api_version = api_versions.APIVersion(
MAX_VERSION)
@ddt.ddt
class TestShareLimitsShow(TestShareLimits):
def setUp(self):
super(TestShareLimitsShow, self).setUp()
# Get the command object to test
self.cmd = osc_share_limits.ShareLimitsShow(self.app, None)
self.absolute_limit_columns = ["Name", "Value"]
self.rate_limit_columns = [
"Verb",
"Regex",
"URI",
"Value",
"Remaining",
"Unit",
"Next Available",
]
@ddt.data('absolute', 'rate')
def test_limits(self, limit_type):
share_limits = (
manila_fakes.FakeShareLimits.create_one_share_limit()
)
self.share_limits_mock.get.return_value = share_limits
expected_data = share_limits._info[f"{limit_type}_limit"]
arglist = []
verifylist = []
if limit_type == 'absolute':
arglist.append('--absolute')
verifylist.extend([
('absolute', True),
('rate', False)
])
else:
arglist.append('--rate')
verifylist.extend([
('absolute', False),
('rate', True)
])
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
actual_columns, actual_data = self.cmd.take_action(parsed_args)
self.assertEqual(getattr(self, f"{limit_type}_limit_columns"),
actual_columns)
if limit_type == 'rate':
expected_data_tuple = tuple(expected_data.values())
self.assertEqual(sorted(expected_data_tuple),
sorted(next(actual_data)))
else:
expected_data_tuple = tuple(expected_data.items())
self.assertEqual(sorted(expected_data_tuple),
sorted(actual_data))

View File

@ -50,6 +50,7 @@ class RateLimit(object):
self.regex = regex
self.value = value
self.remain = remain
self.remaining = self.remain
self.unit = unit
self.next_available = next_available

View File

@ -104,6 +104,7 @@ openstack.share.v2 =
share_instance_list = manilaclient.osc.v2.share_instances:ShareInstanceList
share_instance_set = manilaclient.osc.v2.share_instances:ShareInstanceSet
share_instance_show = manilaclient.osc.v2.share_instances:ShareInstanceShow
share_limits_show = manilaclient.osc.v2.share_limits:ShareLimitsShow
[coverage:run]
omit = manilaclient/tests/*