diff --git a/cloudkittyclient/v2/client.py b/cloudkittyclient/v2/client.py index 2b443cc..ce3b77f 100644 --- a/cloudkittyclient/v2/client.py +++ b/cloudkittyclient/v2/client.py @@ -16,6 +16,7 @@ from cloudkittyclient.v1 import client from cloudkittyclient.v2 import dataframes from cloudkittyclient.v2.rating import modules +from cloudkittyclient.v2 import reprocessing from cloudkittyclient.v2 import scope from cloudkittyclient.v2 import summary @@ -42,3 +43,4 @@ class Client(client.Client): self.scope = scope.ScopeManager(self.api_client) self.summary = summary.SummaryManager(self.api_client) self.rating = modules.RatingManager(self.api_client) + self.reprocessing = reprocessing.ReprocessingManager(self.api_client) diff --git a/cloudkittyclient/v2/reprocessing.py b/cloudkittyclient/v2/reprocessing.py new file mode 100644 index 0000000..50d2b56 --- /dev/null +++ b/cloudkittyclient/v2/reprocessing.py @@ -0,0 +1,78 @@ +# 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 cloudkittyclient.common import base +from cloudkittyclient import exc + + +class ReprocessingManager(base.BaseManager): + """Class used to handle /v2/task/reprocesses endpoint""" + + url = '/v2/task/reprocesses' + + url_to_post = '/v2/task/reprocess' + + def get_reprocessing_tasks(self, offset=0, limit=100, scope_ids=[], + order="DESC", **kwargs): + """Returns a paginated list of reprocessing tasks. + + Some optional filters can be provided. + + :param offset: Index of the first reprocessing task + that should be returned. + :type offset: int + :param limit: Maximal number of reprocessing task to return. + :type limit: int + :param scope_ids: Optional scope_ids to filter on. + :type scope_ids: list of str + :param order: Optional order (asc/desc) to sort tasks. + :type order: str + """ + kwargs = kwargs or {} + kwargs['order'] = order + kwargs['offset'] = offset + kwargs['limit'] = limit + + authorized_args = ['offset', 'limit', 'order'] + url = self.get_url(None, kwargs, authorized_args=authorized_args) + + if scope_ids: + url += "&scope_ids=%s" % (",".join(scope_ids)) + return self.api_client.get(url).json() + + def post_reprocessing_task(self, scope_ids=[], start=None, end=None, + reason=None, **kwargs): + """Creates a reprocessing task + + :param start: The start date of the reprocessing task + :type start: timeutils.parse_isotime + :param end: The end date of the reprocessing task + :type end: timeutils.parse_isotime + :param scope_ids: The scope IDs to create the reprocessing task to + :type scope_ids: list of str + :param reason: The reason for the reprocessing task + :type reason: str + """ + + if not scope_ids: + raise exc.ArgumentRequired("'scope-id' argument is required") + + body = dict( + scope_ids=scope_ids, + start_reprocess_time=start, + end_reprocess_time=end, + reason=reason + ) + + body = dict(filter(lambda elem: bool(elem[1]), body.items())) + + return self.api_client.post(self.url_to_post, json=body).json() diff --git a/cloudkittyclient/v2/reprocessing_cli.py b/cloudkittyclient/v2/reprocessing_cli.py new file mode 100644 index 0000000..4661018 --- /dev/null +++ b/cloudkittyclient/v2/reprocessing_cli.py @@ -0,0 +1,95 @@ +# 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 cliff import lister +from oslo_utils import timeutils + +from cloudkittyclient import utils + + +class CliReprocessingTasksGet(lister.Lister): + """Get reprocessing tasks.""" + + result_columns = [ + ('scope_id', 'Scope ID'), + ('reason', 'Reason'), + ('start_reprocess_time', 'Start reprocessing time'), + ('end_reprocess_time', 'End reprocessing time'), + ('current_reprocess_time', 'Current reprocessing time'), + ] + + def get_parser(self, prog_name): + parser = super(CliReprocessingTasksGet, self).get_parser(prog_name) + + parser.add_argument('--scope-id', type=str, default=[], + action='append', help='Optional filter on scope ' + 'IDs. This filter can be ' + 'used multiple times.') + + parser.add_argument('--offset', type=int, default=0, + help='Index of the first scope. ' + 'The default value is 0.') + parser.add_argument('--limit', type=int, default=100, + help='Maximal number of scopes. ' + 'The default value is 100.') + parser.add_argument('--order', type=str, default="DESC", + help='The order to sort the reprocessing tasks ' + '(ASC or DESC).') + + return parser + + def take_action(self, parsed_args): + resp = utils.get_client_from_osc( + self).reprocessing.get_reprocessing_tasks( + scope_ids=parsed_args.scope_id, offset=parsed_args.offset, + limit=parsed_args.limit, order=parsed_args.order + ) + + values = utils.list_to_cols(resp['results'], self.result_columns) + return [col[1] for col in self.result_columns], values + + +class CliReprocessingTasksPost(lister.Lister): + """Create a reprocessing task.""" + + def get_parser(self, prog_name): + parser = super(CliReprocessingTasksPost, self).get_parser(prog_name) + + parser.add_argument('--scope-id', type=str, default=[], + action='append', + help='The scope IDs to reprocess. This option can ' + 'be used multiple times to execute the same ' + 'reprocessing task for different scope IDs.') + + parser.add_argument('--start-reprocess-time', + type=timeutils.parse_isotime, + help="Start of the period to reprocess in ISO8601 " + "format. Example: '2022-04-22T00:00:00Z.'") + + parser.add_argument('--end-reprocess-time', + type=timeutils.parse_isotime, + help="End of the period to reprocess in ISO8601 " + "format. Example: '2022-04-22T00:00:00Z.'") + + parser.add_argument('--reason', type=str, + help="The reason to create the reprocessing task.") + + return parser + + def take_action(self, parsed_args): + return ["Result"], utils.get_client_from_osc( + self).reprocessing.post_reprocessing_task( + scope_ids=parsed_args.scope_id, + start=parsed_args.start_reprocess_time, + end=parsed_args.end_reprocess_time, + reason=parsed_args.reason + ) diff --git a/releasenotes/notes/add-reprocess-api-support-dafc30d0d08a34fd.yaml b/releasenotes/notes/add-reprocess-api-support-dafc30d0d08a34fd.yaml new file mode 100644 index 0000000..51f7ab8 --- /dev/null +++ b/releasenotes/notes/add-reprocess-api-support-dafc30d0d08a34fd.yaml @@ -0,0 +1,10 @@ +--- +features: + - | + Introduce reprocessing task API in the CLI. The following new commands + are added to the OpenStack CLI "rating tasks reprocessing get" and + "rating tasks reprocessing create". For CloudKitty CLI, we added the + following new commands "tasks reprocessing get" and "tasks reprocessing + create". Both command sets work in a similar fashion, but one is + targetting the OpenStack CLI integration, whereas the other is + targetting CloudKitty client only. \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index c076612..43e95ec 100644 --- a/setup.cfg +++ b/setup.cfg @@ -89,6 +89,9 @@ openstack.rating.v1 = rating_pyscript_delete = cloudkittyclient.v1.rating.pyscripts_cli:CliDeleteScript openstack.rating.v2 = + rating_tasks_reprocessing_get = cloudkittyclient.v2.reprocessing_cli:CliReprocessingTasksGet + rating_tasks_reprocessing_create = cloudkittyclient.v2.reprocessing_cli:CliReprocessingTasksPost + rating_dataframes_get = cloudkittyclient.v2.dataframes_cli:CliDataframesGet rating_dataframes_add = cloudkittyclient.v2.dataframes_cli:CliDataframesAdd @@ -206,6 +209,9 @@ cloudkittyclient_v1 = pyscript_delete = cloudkittyclient.v1.rating.pyscripts_cli:CliDeleteScript cloudkittyclient_v2 = + tasks_reprocessing_get = cloudkittyclient.v2.reprocessing_cli:CliReprocessingTasksGet + tasks_reprocessing_create = cloudkittyclient.v2.reprocessing_cli:CliReprocessingTasksPost + dataframes_add = cloudkittyclient.v2.dataframes_cli:CliDataframesAdd dataframes_get = cloudkittyclient.v2.dataframes_cli:CliDataframesGet