Add support for PUT /v2/scope API endpoint to the client
This allows to reset the state of one or several scopes through the API via the client library and cli tool. Change-Id: I69ce9a1c2ee0d8a6dd191a39e5c843e0baa1290f Story: 2005395 Task: 30794
This commit is contained in:
parent
c138f409b1
commit
d660bef837
|
@ -27,6 +27,12 @@ class CkScopeTest(base.BaseFunctionalTest):
|
|||
# the state of a scope through the client
|
||||
# resp = self.runner('scope state get')
|
||||
|
||||
def test_scope_state_reset(self):
|
||||
return True
|
||||
# FIXME(jferrieu): Uncomment and update this once there is a way to set
|
||||
# the state of a scope through the client
|
||||
# resp = self.runner('scope state reset')
|
||||
|
||||
|
||||
class OSCScopeTest(CkScopeTest):
|
||||
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
from cloudkittyclient import exc
|
||||
from cloudkittyclient.tests.unit.v2 import base
|
||||
import datetime
|
||||
|
||||
|
||||
class TestScope(base.BaseAPIEndpointTestCase):
|
||||
|
@ -29,3 +31,58 @@ class TestScope(base.BaseAPIEndpointTestCase):
|
|||
except AssertionError:
|
||||
self.api_client.get.assert_called_once_with(
|
||||
'/v2/scope?offset=10&limit=10')
|
||||
|
||||
def test_reset_scope_with_args(self):
|
||||
self.scope.reset_scope_state(
|
||||
state=datetime.datetime(2019, 5, 7),
|
||||
all_scopes=True)
|
||||
self.api_client.put.assert_called_once_with(
|
||||
'/v2/scope',
|
||||
json={
|
||||
'state': datetime.datetime(2019, 5, 7),
|
||||
'all_scopes': True,
|
||||
})
|
||||
|
||||
def test_reset_scope_with_list_args(self):
|
||||
self.scope.reset_scope_state(
|
||||
state=datetime.datetime(2019, 5, 7),
|
||||
scope_id=['id1', 'id2'],
|
||||
all_scopes=False)
|
||||
self.api_client.put.assert_called_once_with(
|
||||
'/v2/scope',
|
||||
json={
|
||||
'state': datetime.datetime(2019, 5, 7),
|
||||
'scope_id': 'id1,id2',
|
||||
})
|
||||
|
||||
def test_reset_scope_strips_none_and_false_args(self):
|
||||
self.scope.reset_scope_state(
|
||||
state=datetime.datetime(2019, 5, 7),
|
||||
all_scopes=False,
|
||||
scope_key=None,
|
||||
scope_id=['id1', 'id2'])
|
||||
self.api_client.put.assert_called_once_with(
|
||||
'/v2/scope',
|
||||
json={
|
||||
'state': datetime.datetime(2019, 5, 7),
|
||||
'scope_id': 'id1,id2',
|
||||
})
|
||||
|
||||
def test_reset_scope_with_no_args_raises_exc(self):
|
||||
self.assertRaises(
|
||||
exc.ArgumentRequired,
|
||||
self.scope.reset_scope_state)
|
||||
|
||||
def test_reset_scope_with_lacking_args_raises_exc(self):
|
||||
self.assertRaises(
|
||||
exc.ArgumentRequired,
|
||||
self.scope.reset_scope_state,
|
||||
state=datetime.datetime(2019, 5, 7))
|
||||
|
||||
def test_reset_scope_with_both_args_raises_exc(self):
|
||||
self.assertRaises(
|
||||
exc.InvalidArgumentError,
|
||||
self.scope.reset_scope_state,
|
||||
state=datetime.datetime(2019, 5, 7),
|
||||
scope_id=['id1', 'id2'],
|
||||
all_scopes=True)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# under the License.
|
||||
#
|
||||
from cloudkittyclient.common import base
|
||||
from cloudkittyclient import exc
|
||||
|
||||
|
||||
class ScopeManager(base.BaseManager):
|
||||
|
@ -48,3 +49,54 @@ class ScopeManager(base.BaseManager):
|
|||
'offset', 'limit', 'collector', 'fetcher', 'scope_id', 'scope_key']
|
||||
url = self.get_url(None, kwargs, authorized_args=authorized_args)
|
||||
return self.api_client.get(url).json()
|
||||
|
||||
def reset_scope_state(self, **kwargs):
|
||||
"""Returns nothing.
|
||||
|
||||
Some optional filters can be provided.
|
||||
The all_scopes and the scope_id options are mutually exclusive and one
|
||||
must be provided.
|
||||
|
||||
:param state: datetime object from which the state will be reset
|
||||
:type state: datetime.datetime
|
||||
:param all_scopes: Whether all scopes must be reset
|
||||
:type all_scopes: bool
|
||||
:param collector: Optional collector to filter on.
|
||||
:type collector: str or list of str
|
||||
:param fetcher: Optional fetcher to filter on.
|
||||
:type fetcher: str or list of str
|
||||
:param scope_id: Optional scope_id to filter on.
|
||||
:type scope_id: str or list of str
|
||||
:param scope_key: Optional scope_key to filter on.
|
||||
:type scope_key: str or list of str
|
||||
"""
|
||||
|
||||
if not kwargs.get('state'):
|
||||
raise exc.ArgumentRequired("'state' argument is required")
|
||||
|
||||
if not kwargs.get('all_scopes') and not kwargs.get('scope_id'):
|
||||
raise exc.ArgumentRequired(
|
||||
"You must specify either 'scope_id' or 'all_scopes'")
|
||||
|
||||
if kwargs.get('all_scopes') and kwargs.get('scope_id'):
|
||||
raise exc.InvalidArgumentError(
|
||||
"You can't specify both 'scope_id' and 'all_scopes'")
|
||||
|
||||
for key in ('collector', 'fetcher', 'scope_id', 'scope_key'):
|
||||
if key in kwargs.keys():
|
||||
if isinstance(kwargs[key], list):
|
||||
kwargs[key] = ','.join(kwargs[key])
|
||||
|
||||
body = dict(
|
||||
state=kwargs.get('state'),
|
||||
scope_id=kwargs.get('scope_id'),
|
||||
scope_key=kwargs.get('scope_key'),
|
||||
collector=kwargs.get('collector'),
|
||||
fetcher=kwargs.get('fetcher'),
|
||||
all_scopes=kwargs.get('all_scopes'),
|
||||
)
|
||||
# Stripping None and False values
|
||||
body = dict(filter(lambda elem: bool(elem[1]), body.items()))
|
||||
|
||||
url = self.get_url(None, kwargs)
|
||||
return self.api_client.put(url, json=body)
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
from cliff import command
|
||||
from cliff import lister
|
||||
from oslo_utils import timeutils
|
||||
|
||||
from cloudkittyclient import utils
|
||||
|
||||
|
@ -53,3 +55,44 @@ class CliScopeStateGet(lister.Lister):
|
|||
)
|
||||
values = utils.list_to_cols(resp['results'], self.info_columns)
|
||||
return [col[1] for col in self.info_columns], values
|
||||
|
||||
|
||||
class CliScopeStateReset(command.Command):
|
||||
"""Reset the state of several scopes."""
|
||||
info_columns = [
|
||||
('scope_id', 'Scope ID'),
|
||||
('scope_key', 'Scope Key'),
|
||||
('collector', 'Collector'),
|
||||
('fetcher', 'Fetcher'),
|
||||
]
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CliScopeStateReset, self).get_parser(prog_name)
|
||||
|
||||
for col in self.info_columns:
|
||||
parser.add_argument(
|
||||
'--' + col[0].replace('_', '-'), type=str,
|
||||
action='append', help='Optional filter on ' + col[1])
|
||||
|
||||
parser.add_argument(
|
||||
'-a', '--all-scopes',
|
||||
action='store_true',
|
||||
help="Target all scopes at once")
|
||||
|
||||
parser.add_argument(
|
||||
'state',
|
||||
type=timeutils.parse_isotime,
|
||||
help="State iso8601 datetime to which the state should be set. "
|
||||
"Example: 2019-06-01T00:00:00Z.")
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
utils.get_client_from_osc(self).scope.reset_scope_state(
|
||||
collector=parsed_args.collector,
|
||||
fetcher=parsed_args.fetcher,
|
||||
scope_id=parsed_args.scope_id,
|
||||
scope_key=parsed_args.scope_key,
|
||||
all_scopes=parsed_args.all_scopes,
|
||||
state=parsed_args.state,
|
||||
)
|
||||
|
|
|
@ -87,6 +87,8 @@ openstack.rating.v1 =
|
|||
|
||||
openstack.rating.v2 =
|
||||
rating_scope_state_get = cloudkittyclient.v2.scope_cli:CliScopeStateGet
|
||||
rating_scope_state_reset = cloudkittyclient.v2.scope_cli:CliScopeStateReset
|
||||
|
||||
rating_summary_get = cloudkittyclient.v2.summary_cli:CliSummaryGet
|
||||
|
||||
rating_report_tenant_list = cloudkittyclient.v1.report_cli:CliTenantList
|
||||
|
@ -199,6 +201,8 @@ cloudkittyclient.v1 =
|
|||
|
||||
cloudkittyclient.v2 =
|
||||
scope_state_get = cloudkittyclient.v2.scope_cli:CliScopeStateGet
|
||||
scope_state_reset = cloudkittyclient.v2.scope_cli:CliScopeStateReset
|
||||
|
||||
summary_get = cloudkittyclient.v2.summary_cli:CliSummaryGet
|
||||
|
||||
report_tenant_list = cloudkittyclient.v1.report_cli:CliTenantList
|
||||
|
|
Loading…
Reference in New Issue