Compare commits

..

15 Commits
4.3.0 ... 4.6.0

Author SHA1 Message Date
Zuul
07d4e86ca4 Merge "Add Python3 zed unit tests" 2022-08-08 15:20:12 +00:00
Zuul
6bd44e7413 Merge "Introduce reprocessing task API in the CLI" 2022-08-08 15:20:10 +00:00
Zuul
c30878e414 Merge "Introduce the patch scope API in the CLI" 2022-08-08 15:01:18 +00:00
Elod Illes
eb0cac7148 Add Python3 zed unit tests
This is an automatically generated patch to ensure unit testing
is in place for all the of the tested runtimes for zed.

See also the PTI in governance [1].

[1]: https://governance.openstack.org/tc/reference/project-testing-interface.html

Change-Id: If9b21c3e9628a945d618c38b015196544a69ae8c
2022-08-08 15:51:48 +02:00
Rafael Weingärtner
187b0ce70c Introduce the patch scope API in the CLI
Change-Id: I8134020c409bc6c3e80bf996890e6609e1a763b9
2022-08-08 10:49:42 -03:00
Rafael Weingärtner
277b47779f Introduce reprocessing task API in the CLI
Change-Id: Ieab5df4deb9cbf5eddfc8eca3b028942f6303abd
2022-08-08 10:46:50 -03:00
Ghanshyam Mann
19c0ebad5b Drop lower-constraints.txt and its testing
As discussed in TC PTG[1] and TC resolution[2], we are
dropping the lower-constraints.txt file and its testing.
We will keep lower bounds in the requirements.txt file but
with a note that these are not tested lower bounds and we
try our best to keep them updated.

[1] https://etherpad.opendev.org/p/tc-zed-ptg#L326
[2] https://governance.openstack.org/tc/resolutions/20220414-drop-lower-constraints.html#proposal

Change-Id: I9261e86576e328b28a6c4442731e2ebbb414eb4d
2022-04-30 15:56:26 -05:00
de6c8b22c5 Update master for stable/yoga
Add file to the reno documentation build to show release notes for
stable/yoga.

Use pbr instruction to increment the minor version number
automatically so that master versions are higher than the versions on
stable/yoga.

Sem-Ver: feature
Change-Id: Ib59df27f2c771cb407b267fbcedee3588eb83049
2022-03-03 10:51:04 +00:00
Sam Morrison
783cc22662 Add response_format to list of available args for v2 summary API
This was added in cloudkitty with commit
6ba9d45ea6

Change-Id: Id091ee9f61c2863ed3ea1aaf5d967edf417df22a
2022-02-11 13:16:01 +11:00
Ghanshyam Mann
20003a58ce Re-add python 3.6/3.7 in classifier
We have updated the yoga testing runtime to keep the
py36 testing.

- https://review.opendev.org/c/openstack/governance/+/820195

Unit tests job template is also updated to keep python
3.6 as a voting job. So with the py3.6 and py3.9 testing as voting
job template, we are keeping python 3.6, 3.7, 3.8, and 3.8 as
tested versions in the Yoga cycle.

- https://review.opendev.org/c/openstack/openstack-zuul-jobs/+/820286

This commit re-add the python 3.6/3.7 versions in setup.cfg classifier.

Change-Id: Iaf4b4a82b5a50b3ef2dc793c50ef1b0981f37856
2021-12-13 19:18:27 -06:00
Ghanshyam Mann
719f4cff6a Updating python testing as per Yoga testing runtime
Yoga testing runtime has been updated with py38 and py39
as voting and removed the py36 testing. Unit tests update are
handled by the job template change in openstack-zuul-job

- https://review.opendev.org/c/openstack/openstack-zuul-jobs/+/818609

this commit makes other required changes in setup.cfg metadata.

[1] https://governance.openstack.org/tc/reference/runtimes/yoga.html

Change-Id: Idd8da33c954234b7c5d2d969c50da8aee4bf7904
2021-11-24 19:11:11 -06:00
wu.shiming
64ab6b412a Replace deprecated assertRaisesRegexp
The assertRaisesRegexp method has been deprecated since it was renamed
to assertRaisesRegex in Python 3.2.

https://docs.python.org/3/library/unittest.html#deprecated-aliases

Change-Id: Ibab4d14764372298cc0055f168ff44eabdc873f0
2021-11-09 09:04:34 +08:00
Pierre Riteau
85317b6773 Fix capitalisation of CloudKitty
This is really an excuse to force generating release notes which are
missing for Xena.

Change-Id: Ie8459f44142a981ee3475dd9b2688d155c852376
2021-09-24 09:48:01 +02:00
6e10961c49 Add Python3 yoga unit tests
This is an automatically generated patch to ensure unit testing
is in place for all the of the tested runtimes for yoga.

See also the PTI in governance [1].

[1]: https://governance.openstack.org/tc/reference/project-testing-interface.html

Change-Id: I8e6532689aed280ce32a6b33dbb7b26bfb6c8044
2021-09-10 14:33:13 +00:00
2454c59cb2 Update master for stable/xena
Add file to the reno documentation build to show release notes for
stable/xena.

Use pbr instruction to increment the minor version number
automatically so that master versions are higher than the versions on
stable/xena.

Sem-Ver: feature
Change-Id: I408828a8e29a418dba134bed8cd7a94206b26132
2021-09-10 14:33:08 +00:00
19 changed files with 310 additions and 45 deletions

View File

@@ -43,10 +43,9 @@
- project:
templates:
- openstack-lower-constraints-jobs
- check-requirements
- openstack-cover-jobs
- openstack-python3-xena-jobs
- openstack-python3-zed-jobs
- openstackclient-plugin-jobs
- publish-openstack-docs-pti
- release-notes-jobs-python3

View File

@@ -137,7 +137,7 @@ class CkDataframesTest(base.BaseFunctionalTest):
super(CkDataframesTest, self).tearDown()
def test_dataframes_add_with_no_args(self):
self.assertRaisesRegexp(
self.assertRaisesRegex(
RuntimeError,
'error: the following arguments are required: datafile',
self.runner,

View File

@@ -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)

View File

@@ -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()

View File

@@ -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
)

View File

@@ -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()

View File

@@ -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)

View File

@@ -36,6 +36,8 @@ class SummaryManager(base.BaseManager):
:type begin: datetime.datetime
:param end: End of the period to gather data from
:type end: datetime.datetime
:param response_format: Either 'table' or 'object' defaults to 'table'
:type response_format: str
"""
if 'groupby' in kwargs.keys() and isinstance(kwargs['groupby'], list):
kwargs['groupby'] = ','.join(kwargs['groupby'])
@@ -46,7 +48,8 @@ class SummaryManager(base.BaseManager):
)
authorized_args = [
'offset', 'limit', 'filters', 'groupby', 'begin', 'end']
'offset', 'limit', 'filters', 'groupby', 'begin', 'end',
'response_format']
url = self.get_url(None, kwargs, authorized_args=authorized_args)
return self.api_client.get(url).json()

View File

@@ -22,7 +22,7 @@ Please refer the `python-cloudkittyclient Core Team
New Feature Planning
~~~~~~~~~~~~~~~~~~~~
Cloudkitty features are tracked on `Storyboard <https://storyboard.openstack.org/#!/project/895>`_.
CloudKitty features are tracked on `Storyboard <https://storyboard.openstack.org/#!/project/895>`_.
Task Tracking
~~~~~~~~~~~~~

View File

@@ -1,23 +0,0 @@
# requirements
pbr==5.5.1 # Apache-2.0
cliff==3.5.0 # Apache-2.0
keystoneauth1==4.3.0 # Apache-2.0
oslo.utils==4.7.0 # Apache-2.0
oslo.log==4.4.0 # Apache-2.0
PyYAML==5.3.1 # MIT
jsonpath-rw-ext==1.2.0 # Apache-2.0
os-client-config==2.1.0 # Apache-2.0
osc-lib==2.3.0 # Apache-2.0
# test-requirements.txt
pyflakes==2.1.1
coverage==4.0 # Apache-2.0
python-subunit==1.4.0 # Apache-2.0/BSD
oslotest==1.10.0 # Apache-2.0
stestr==2.0 # Apache-2.0
python-openstackclient==3.14 # Apache-2.0
# doc/requirements.txt
openstackdocstheme==1.30.0 # Apache-2.0
sphinx==1.6.2 # BSD
reno==2.5.0 # Apache2

View File

@@ -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.

View File

@@ -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.

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Cloudkitty Release Notes documentation build configuration file.
# CloudKitty Client Release Notes documentation build configuration file.
#
# This file is execfile()d with the current directory set to its
# containing dir.
@@ -42,8 +42,8 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
project = u'Cloudkitty Client Release Notes'
copyright = u'2016, Cloudkitty developers'
project = u'CloudKitty Client Release Notes'
copyright = u'2016, CloudKitty developers'
# Release notes are version independent.
# The short X.Y version.
@@ -173,7 +173,7 @@ html_static_path = ['_static']
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'CloudkittyReleaseNotestdoc'
htmlhelp_basename = 'CloudKittyClientReleaseNotestdoc'
# -- Options for LaTeX output ---------------------------------------------
@@ -193,8 +193,9 @@ latex_elements = {
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'PythonCloudkitty.tex', u'Cloudkitty Release Notes Documentation',
u'Cloudkitty developers', 'manual'),
('index', 'PythonCloudKittyClient.tex',
u'CloudKitty Client Release Notes Documentation',
u'CloudKitty developers', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
@@ -224,8 +225,8 @@ latex_documents = [
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'cloudkittyclient',
u'Cloudkitty Client Release Notes Documentation',
[u'Cloudkitty developers'], 1)
u'CloudKitty Client Release Notes Documentation',
[u'CloudKitty developers'], 1)
]
# If true, show URL addresses after external links.
@@ -239,8 +240,8 @@ man_pages = [
# dir menu entry, description, category)
texinfo_documents = [
('index', 'cloudkittyclient',
u'Cloudkitty Client Release Notes Documentation',
u'Cloudkitty Client developers', 'Cloudkittyclient',
u'CloudKitty Client Release Notes Documentation',
u'CloudKitty Client developers', 'CloudKittyClient',
'One line description of project.', 'Miscellaneous'),
]

View File

@@ -1,4 +1,4 @@
Welcome to Cloudkitty Client Release Notes documentation!
Welcome to CloudKitty Client Release Notes documentation!
=========================================================
Contents
@@ -8,6 +8,8 @@ Contents
:maxdepth: 2
unreleased
yoga
xena
wallaby
victoria
ussuri

View File

@@ -0,0 +1,6 @@
=========================
Xena Series Release Notes
=========================
.. release-notes::
:branch: stable/xena

View File

@@ -0,0 +1,6 @@
=========================
Yoga Series Release Notes
=========================
.. release-notes::
:branch: stable/yoga

View File

@@ -1,3 +1,7 @@
# Requirements lower bounds listed here are our best effort to keep them up to
# date but we do not test them so no guarantee of having them all correct. If
# you find any incorrect lower bounds, let us know or propose a fix.
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.

View File

@@ -20,6 +20,7 @@ classifier =
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
[files]
packages =
@@ -88,11 +89,15 @@ 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
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
@@ -204,11 +209,15 @@ 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
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

View File

@@ -76,9 +76,3 @@ deps =
-r{toxinidir}/doc/requirements.txt
commands =
sphinx-build -a -E -W -d releasenotes/build/doctrees --keep-going -b html releasenotes/source releasenotes/build/html
[testenv:lower-constraints]
deps =
-c{toxinidir}/lower-constraints.txt
-r{toxinidir}/test-requirements.txt
-r{toxinidir}/requirements.txt