diff --git a/cloudkittyclient/v2/scope.py b/cloudkittyclient/v2/scope.py index a3d1aa7..fc8a279 100644 --- a/cloudkittyclient/v2/scope.py +++ b/cloudkittyclient/v2/scope.py @@ -15,6 +15,8 @@ from cloudkittyclient.common import base from cloudkittyclient import exc +from distutils.util import strtobool + class ScopeManager(base.BaseManager): """Class used to handle /v2/scope endpoint""" @@ -100,3 +102,41 @@ class ScopeManager(base.BaseManager): url = self.get_url(None, kwargs) return self.api_client.put(url, json=body) + + def update_scope(self, **kwargs): + """Update storage scope + + The `scope_id field` is mandatory, and all other are optional. Only the + attributes sent will be updated. The attributes that are not sent will + not be changed in the backend. + + :param collector: collector to be used by the scope. + :type collector: str + :param fetcher: fetcher to be used by the scope. + :type fetcher: str + :param scope_id: Mandatory scope_id to update. + :type scope_id: str + :param scope_key: scope_key to be used by the scope. + :type scope_key: str + :param active: Indicates if the scope is active or not + :type active: str + """ + + if not kwargs.get('scope_id'): + raise exc.ArgumentRequired("'scope_id' argument is required") + + body = dict( + scope_id=kwargs.get('scope_id'), + scope_key=kwargs.get('scope_key'), + collector=kwargs.get('collector'), + fetcher=kwargs.get('fetcher') + ) + + if kwargs.get('active'): + body['active'] = strtobool(kwargs.get('active')) + + # Stripping None + body = dict(filter(lambda elem: elem[1] is not None, body.items())) + + url = self.get_url(None, kwargs) + return self.api_client.patch(url, json=body).json() diff --git a/cloudkittyclient/v2/scope_cli.py b/cloudkittyclient/v2/scope_cli.py index 96015d3..ecd42be 100644 --- a/cloudkittyclient/v2/scope_cli.py +++ b/cloudkittyclient/v2/scope_cli.py @@ -96,3 +96,36 @@ class CliScopeStateReset(command.Command): all_scopes=parsed_args.all_scopes, state=parsed_args.state, ) + + +class CliPatchScope(command.Command): + """Update scope attributes.""" + + info_columns = [ + ('scope_key', 'Scope Key'), + ('collector', 'Collector'), + ('fetcher', 'Fetcher'), + ('active', 'Active'), + ] + + def get_parser(self, prog_name): + parser = super(CliPatchScope, self).get_parser(prog_name) + + for col in self.info_columns: + parser.add_argument( + '--' + col[0].replace('_', '-'), type=str, + help='Optional filter on ' + col[1]) + + parser.add_argument( + '-id', '--scope-id', required=True, type=str, + help="The scope ID to be updated") + + return parser + + def take_action(self, parsed_args): + return utils.get_client_from_osc(self).scope.update_scope( + collector=parsed_args.collector, + fetcher=parsed_args.fetcher, + scope_id=parsed_args.scope_id, + scope_key=parsed_args.scope_key, + active=parsed_args.active) diff --git a/releasenotes/notes/add-patch-scope-support-04c408f982d7d352.yaml b/releasenotes/notes/add-patch-scope-support-04c408f982d7d352.yaml new file mode 100644 index 0000000..2c62bff --- /dev/null +++ b/releasenotes/notes/add-patch-scope-support-04c408f982d7d352.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Introduce the patch scope API in the CLI. The command "rating scope + patch" is added to the OpenStack CLI with this patch, and the command + "scope patch" is added to the CloudKitty python client. diff --git a/setup.cfg b/setup.cfg index 7807c00..c076612 100644 --- a/setup.cfg +++ b/setup.cfg @@ -94,6 +94,7 @@ openstack.rating.v2 = rating_scope_state_get = cloudkittyclient.v2.scope_cli:CliScopeStateGet rating_scope_state_reset = cloudkittyclient.v2.scope_cli:CliScopeStateReset + rating_scope_patch = cloudkittyclient.v2.scope_cli:CliPatchScope rating_summary_get = cloudkittyclient.v2.summary_cli:CliSummaryGet @@ -210,6 +211,7 @@ cloudkittyclient_v2 = scope_state_get = cloudkittyclient.v2.scope_cli:CliScopeStateGet scope_state_reset = cloudkittyclient.v2.scope_cli:CliScopeStateReset + scope_patch = cloudkittyclient.v2.scope_cli:CliPatchScope summary_get = cloudkittyclient.v2.summary_cli:CliSummaryGet