Compare commits
41 Commits
4.2.0
...
unmaintain
| Author | SHA1 | Date | |
|---|---|---|---|
| 0290a564a6 | |||
|
|
d75d74d49f | ||
| 33531ada6d | |||
| e6e18c1157 | |||
|
|
d30991cefa | ||
| 36566c32fc | |||
|
|
3e9fd5b540 | ||
| 255a871785 | |||
|
|
244f229af7 | ||
| 0835706738 | |||
| 97dc4d64da | |||
| 0c97e40e2b | |||
|
|
0ee5e17ee5 | ||
|
|
07d4e86ca4 | ||
|
|
6bd44e7413 | ||
|
|
c30878e414 | ||
|
|
eb0cac7148 | ||
|
|
187b0ce70c | ||
|
|
277b47779f | ||
|
|
19c0ebad5b | ||
| de6c8b22c5 | |||
|
|
783cc22662 | ||
|
|
20003a58ce | ||
|
|
719f4cff6a | ||
|
|
64ab6b412a | ||
|
|
85317b6773 | ||
| 6e10961c49 | |||
| 2454c59cb2 | |||
|
|
647f561532 | ||
|
|
61ef2c337e | ||
|
|
b1df2b5ccc | ||
|
|
68fd0e9e33 | ||
|
|
eb7f5e46bb | ||
|
|
0608c0527b | ||
|
|
754e06c51c | ||
|
|
d12e5a821c | ||
|
|
d2c2323bf8 | ||
|
|
67fae0ff52 | ||
|
|
73668bebb0 | ||
| dc606b1d3c | |||
| 5141971122 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,3 +16,4 @@ dist
|
||||
AUTHORS
|
||||
ChangeLog
|
||||
releasenotes/build
|
||||
.idea/
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
host=review.opendev.org
|
||||
port=29418
|
||||
project=openstack/python-cloudkittyclient.git
|
||||
defaultbranch=unmaintained/2024.1
|
||||
|
||||
@@ -43,12 +43,12 @@
|
||||
|
||||
- project:
|
||||
templates:
|
||||
- openstack-lower-constraints-jobs
|
||||
- check-requirements
|
||||
- openstack-cover-jobs
|
||||
- openstack-python3-wallaby-jobs
|
||||
- openstack-python3-jobs
|
||||
- openstackclient-plugin-jobs
|
||||
- publish-openstack-docs-pti
|
||||
- release-notes-jobs-python3
|
||||
check:
|
||||
jobs:
|
||||
- cloudkittyclient-devstack-functional-v1-client:
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
If you would like to contribute to the development of OpenStack,
|
||||
you must follow the steps in this page:
|
||||
The source repository for this project can be found at:
|
||||
|
||||
https://opendev.org/openstack/python-cloudkittyclient
|
||||
|
||||
https://docs.openstack.org/infra/manual/developers.html
|
||||
Pull requests submitted through GitHub are not monitored.
|
||||
|
||||
Once those steps have been completed, changes to OpenStack
|
||||
should be submitted for review via the Gerrit tool, following
|
||||
the workflow documented at:
|
||||
To start contributing to OpenStack, follow the steps in the contribution guide
|
||||
to set up and use Gerrit:
|
||||
|
||||
https://docs.openstack.org/infra/manual/developers.html#development-workflow
|
||||
https://docs.openstack.org/contributors/code-and-documentation/quick-start.html
|
||||
|
||||
Pull requests submitted through GitHub will be ignored.
|
||||
Bugs should be filed on Storyboard:
|
||||
|
||||
Bugs should be filed on Storyboard, not GitHub:
|
||||
https://storyboard.openstack.org/#!/project/895
|
||||
|
||||
https://storyboard.openstack.org/#!/project/openstack/python-cloudkittyclient
|
||||
For more specific information about contributing to this repository, see the
|
||||
python-cloudkittyclient contributor guide:
|
||||
|
||||
https://docs.openstack.org/python-cloudkittyclient/latest/contributor/contributing.html
|
||||
|
||||
@@ -15,26 +15,57 @@
|
||||
#
|
||||
import json
|
||||
import os
|
||||
import shlex
|
||||
import subprocess
|
||||
|
||||
from cloudkittyclient.tests import utils
|
||||
|
||||
from oslo_log import log
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class BaseFunctionalTest(utils.BaseTestCase):
|
||||
|
||||
# DevStack is using VENV by default. Therefore, to execute the commands,
|
||||
# we need to activate the VENV. And, to do that, we need the VENV path.
|
||||
# This path is hardcoded here because we could not find a variable in this
|
||||
# Python code to retrieve the VENV variable from the test machine.
|
||||
# It seems that because of the stack TOX -> stestr -> this python code, and
|
||||
# so on, we are not able to access the DevStack variables here.
|
||||
#
|
||||
# If somebody finds a solution, we can remove the hardcoded path here.
|
||||
DEV_STACK_VENV_BASE_PATH = "/opt/stack/data/venv"
|
||||
|
||||
BASE_COMMAND_WITH_VENV = "source %s/bin/activate && %s "
|
||||
|
||||
def _run(self, executable, action,
|
||||
flags='', params='', fmt='-f json', stdin=None, has_output=True):
|
||||
if not has_output:
|
||||
fmt = ''
|
||||
|
||||
does_venv_exist = not os.system("ls -lah /opt/stack/data/venv")
|
||||
LOG.info("Test to check if the VENV file exist returned: [%s].",
|
||||
does_venv_exist)
|
||||
|
||||
system_variables = os.environ.copy()
|
||||
LOG.info("System variables [%s] found when executing the tests.",
|
||||
system_variables)
|
||||
|
||||
cmd = ' '.join([executable, flags, action, params, fmt])
|
||||
cmd = shlex.split(cmd)
|
||||
|
||||
actual_command_with_venv = self.BASE_COMMAND_WITH_VENV % (
|
||||
self.DEV_STACK_VENV_BASE_PATH, cmd)
|
||||
|
||||
LOG.info("Command being executed: [%s].", actual_command_with_venv)
|
||||
|
||||
p = subprocess.Popen(
|
||||
cmd, env=os.environ.copy(), shell=False,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
stdin=subprocess.PIPE if stdin else None,
|
||||
["bash", "-c", actual_command_with_venv],
|
||||
env=os.environ.copy(), shell=False, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, stdin=subprocess.PIPE if stdin else None
|
||||
)
|
||||
stdout, stderr = p.communicate(input=stdin)
|
||||
LOG.info("Standard output [%s] and error output [%s] for command "
|
||||
"[%s]. ", stdout, stderr, actual_command_with_venv)
|
||||
if p.returncode != 0:
|
||||
raise RuntimeError('"{cmd}" returned {val}: {msg}'.format(
|
||||
cmd=' '.join(cmd), val=p.returncode, msg=stderr))
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
import collections
|
||||
from collections import abc
|
||||
from unittest import mock
|
||||
|
||||
from cloudkittyclient.tests.unit.v1 import base
|
||||
@@ -57,7 +57,7 @@ class TestReportCli(base.BaseAPIEndpointTestCase):
|
||||
|
||||
assert len(result) == 2
|
||||
assert result[0] == ('Tenant ID', )
|
||||
assert isinstance(result[1], collections.Iterable)
|
||||
assert isinstance(result[1], abc.Iterable)
|
||||
|
||||
for res in result[1]:
|
||||
assert isinstance(res, collections.Iterable)
|
||||
assert isinstance(res, abc.Iterable)
|
||||
|
||||
@@ -172,7 +172,7 @@ class HashmapManager(base.BaseManager):
|
||||
:param value: Value of the mapping
|
||||
:type value: str
|
||||
"""
|
||||
if not kwargs.get('cost'):
|
||||
if kwargs.get('cost') is None:
|
||||
raise exc.ArgumentRequired("'cost' argument is required")
|
||||
if not kwargs.get('value'):
|
||||
if not kwargs.get('service_id'):
|
||||
|
||||
@@ -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)
|
||||
|
||||
76
cloudkittyclient/v2/reprocessing.py
Normal file
76
cloudkittyclient/v2/reprocessing.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# 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'
|
||||
|
||||
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, json=body).json()
|
||||
95
cloudkittyclient/v2/reprocessing_cli.py
Normal file
95
cloudkittyclient/v2/reprocessing_cli.py
Normal 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
|
||||
)
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -44,8 +44,8 @@ source_suffix = '.rst'
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'python-cloudkittyclient'
|
||||
copyright = u'2017, OpenStack Foundation'
|
||||
project = 'python-cloudkittyclient'
|
||||
copyright = '2017, OpenStack Foundation'
|
||||
|
||||
# openstackdocstheme options
|
||||
repository_name = 'openstack/python-cloudkittyclient'
|
||||
@@ -99,8 +99,8 @@ latex_elements = {
|
||||
latex_documents = [
|
||||
('index',
|
||||
'doc-%s.tex' % project,
|
||||
u'%s Documentation' % project,
|
||||
u'OpenStack Foundation', 'howto', True),
|
||||
'%s Documentation' % project,
|
||||
'OpenStack Foundation', 'howto', True),
|
||||
]
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
============
|
||||
Contributing
|
||||
============
|
||||
|
||||
.. include:: ../../CONTRIBUTING.rst
|
||||
47
doc/source/contributor/contributing.rst
Normal file
47
doc/source/contributor/contributing.rst
Normal file
@@ -0,0 +1,47 @@
|
||||
============================
|
||||
So You Want to Contribute...
|
||||
============================
|
||||
For general information on contributing to OpenStack, please check out the
|
||||
`contributor guide <https://docs.openstack.org/contributors/>`_ to get started.
|
||||
It covers all the basics that are common to all OpenStack projects: the accounts
|
||||
you need, the basics of interacting with our Gerrit review system, how we
|
||||
communicate as a community, etc.
|
||||
Below will cover the more project specific information you need to get started
|
||||
with python-cloudkittyclient.
|
||||
|
||||
Communication
|
||||
~~~~~~~~~~~~~
|
||||
* IRC channel #cloudkitty at `OFTC <http://oftc.net>`_
|
||||
* Mailing list (prefix subjects with ``[cloudkitty]`` for faster responses)
|
||||
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-discuss
|
||||
|
||||
Contacting the Core Team
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Please refer the `python-cloudkittyclient Core Team
|
||||
<https://review.opendev.org/admin/groups/4ac765c35f985b3ad9226da07fdcc205c1ce4fe1,members>`_ contacts.
|
||||
|
||||
New Feature Planning
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
CloudKitty features are tracked on `Storyboard <https://storyboard.openstack.org/#!/project/895>`_.
|
||||
|
||||
Task Tracking
|
||||
~~~~~~~~~~~~~
|
||||
We track our tasks in `Storyboard <https://storyboard.openstack.org/#!/project/895>`_.
|
||||
If you're looking for some smaller, easier work item to pick up and get started
|
||||
on, search for the 'low-hanging-fruit' tag.
|
||||
|
||||
Reporting a Bug
|
||||
~~~~~~~~~~~~~~~
|
||||
You found an issue and want to make sure we are aware of it? You can do so on
|
||||
`StoryBoard <https://storyboard.openstack.org/#!/project/895>`_.
|
||||
|
||||
Getting Your Patch Merged
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
All changes proposed to the python-cloudkittyclient project require one or two +2 votes
|
||||
from python-cloudkittyclient core reviewers before one of the core reviewers can approve
|
||||
patch by giving ``Workflow +1`` vote.
|
||||
|
||||
Project Team Lead Duties
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
All common PTL duties are enumerated in the `PTL guide
|
||||
<https://docs.openstack.org/project-team-guide/ptl.html>`_.
|
||||
@@ -12,10 +12,19 @@ Contents:
|
||||
|
||||
install
|
||||
usage
|
||||
contributor
|
||||
cli_reference
|
||||
api_reference/index
|
||||
|
||||
For Contributors
|
||||
================
|
||||
|
||||
* If you are a new contributor to python-cloudkittyclient please refer: :doc:`contributor/contributing`
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
contributor/contributing
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixed a bug where creating a reprocessing task would fail due to sending a
|
||||
POST request to the wrong endpoint.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixes creation of hashmap mappings with a zero cost.
|
||||
6
releasenotes/source/2023.1.rst
Normal file
6
releasenotes/source/2023.1.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
===========================
|
||||
2023.1 Series Release Notes
|
||||
===========================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/2023.1
|
||||
6
releasenotes/source/2023.2.rst
Normal file
6
releasenotes/source/2023.2.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
===========================
|
||||
2023.2 Series Release Notes
|
||||
===========================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/2023.2
|
||||
@@ -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 = 'CloudKitty Client Release Notes'
|
||||
copyright = '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',
|
||||
'CloudKitty Client Release Notes Documentation',
|
||||
'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)
|
||||
'CloudKitty Client Release Notes Documentation',
|
||||
['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',
|
||||
'CloudKitty Client Release Notes Documentation',
|
||||
'CloudKitty Client developers', 'CloudKittyClient',
|
||||
'One line description of project.', 'Miscellaneous'),
|
||||
]
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Welcome to Cloudkitty Client Release Notes documentation!
|
||||
Welcome to CloudKitty Client Release Notes documentation!
|
||||
=========================================================
|
||||
|
||||
Contents
|
||||
@@ -8,6 +8,12 @@ Contents
|
||||
:maxdepth: 2
|
||||
|
||||
unreleased
|
||||
2023.2
|
||||
2023.1
|
||||
zed
|
||||
yoga
|
||||
xena
|
||||
wallaby
|
||||
victoria
|
||||
ussuri
|
||||
train
|
||||
|
||||
6
releasenotes/source/wallaby.rst
Normal file
6
releasenotes/source/wallaby.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
============================
|
||||
Wallaby Series Release Notes
|
||||
============================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/wallaby
|
||||
6
releasenotes/source/xena.rst
Normal file
6
releasenotes/source/xena.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
=========================
|
||||
Xena Series Release Notes
|
||||
=========================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/xena
|
||||
6
releasenotes/source/yoga.rst
Normal file
6
releasenotes/source/yoga.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
=========================
|
||||
Yoga Series Release Notes
|
||||
=========================
|
||||
|
||||
.. release-notes::
|
||||
:branch: unmaintained/yoga
|
||||
6
releasenotes/source/zed.rst
Normal file
6
releasenotes/source/zed.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
========================
|
||||
Zed Series Release Notes
|
||||
========================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/zed
|
||||
@@ -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.
|
||||
|
||||
21
setup.cfg
21
setup.cfg
@@ -1,12 +1,12 @@
|
||||
[metadata]
|
||||
name = python-cloudkittyclient
|
||||
summary = API client of cloudkitty, Rating as a Service project.
|
||||
description-file =
|
||||
description_file =
|
||||
README.rst
|
||||
author = OpenStack
|
||||
author-email = openstack-discuss@lists.openstack.org
|
||||
home-page = https://docs.openstack.org/python-cloudkittyclient/latest/
|
||||
python-requires = >=3.6
|
||||
author_email = openstack-discuss@lists.openstack.org
|
||||
home_page = https://docs.openstack.org/python-cloudkittyclient/latest/
|
||||
python_requires = >=3.8
|
||||
classifier =
|
||||
Environment :: OpenStack
|
||||
Intended Audience :: Information Technology
|
||||
@@ -17,9 +17,10 @@ classifier =
|
||||
Programming Language :: Python :: 3 :: Only
|
||||
Programming Language :: Python :: Implementation :: CPython
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3.6
|
||||
Programming Language :: Python :: 3.7
|
||||
Programming Language :: Python :: 3.8
|
||||
Programming Language :: Python :: 3.9
|
||||
Programming Language :: Python :: 3.10
|
||||
Programming Language :: Python :: 3.11
|
||||
|
||||
[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
|
||||
|
||||
|
||||
51
tox.ini
51
tox.ini
@@ -1,6 +1,6 @@
|
||||
[tox]
|
||||
minversion = 3.1.1
|
||||
envlist = py36,py38,pep8
|
||||
minversion = 3.18.0
|
||||
envlist = py3,pep8
|
||||
skipsdist = True
|
||||
ignore_basepython_conflict = True
|
||||
|
||||
@@ -9,6 +9,7 @@ basepython = python3
|
||||
usedevelop = True
|
||||
install_command = pip install -U {opts} {packages}
|
||||
setenv =
|
||||
DEVSTACK_VENV={env:DEVSTACK_VENV}
|
||||
VIRTUAL_ENV={envdir}
|
||||
deps = -r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
@@ -29,12 +30,40 @@ commands =
|
||||
commands = oslo_debug_helper -t cloudkittyclient/tests {posargs}
|
||||
|
||||
[testenv:functional-v1]
|
||||
passenv = OS_CLOUD OS_PROJECT_DOMAIN_ID OS_USER_DOMAIN_ID OS_PROJECT_DOMAIN_NAME OS_USER_DOMAIN_NAME OS_PROJECT_NAME OS_IDENTITY_API_VERSION OS_PASSWORD OS_AUTH_TYPE OS_AUTH_URL OS_USERNAME OS_ENDPOINT
|
||||
passenv =
|
||||
OS_CLOUD
|
||||
OS_PROJECT_DOMAIN_ID
|
||||
OS_USER_DOMAIN_ID
|
||||
OS_PROJECT_DOMAIN_NAME
|
||||
OS_USER_DOMAIN_NAME
|
||||
OS_PROJECT_NAME
|
||||
OS_IDENTITY_API_VERSION
|
||||
OS_PASSWORD
|
||||
OS_AUTH_TYPE
|
||||
OS_AUTH_URL
|
||||
OS_USERNAME
|
||||
OS_ENDPOINT
|
||||
DEVSTACK_VENV
|
||||
VIRTUAL_ENV
|
||||
setenv = OS_RATING_API_VERSION=1
|
||||
commands = stestr run --concurrency=1 --test-path ./cloudkittyclient/tests/functional/v1
|
||||
|
||||
[testenv:functional-v2]
|
||||
passenv = OS_CLOUD OS_PROJECT_DOMAIN_ID OS_USER_DOMAIN_ID OS_PROJECT_DOMAIN_NAME OS_USER_DOMAIN_NAME OS_PROJECT_NAME OS_IDENTITY_API_VERSION OS_PASSWORD OS_AUTH_TYPE OS_AUTH_URL OS_USERNAME OS_ENDPOINT
|
||||
passenv =
|
||||
OS_CLOUD
|
||||
OS_PROJECT_DOMAIN_ID
|
||||
OS_USER_DOMAIN_ID
|
||||
OS_PROJECT_DOMAIN_NAME
|
||||
OS_USER_DOMAIN_NAME
|
||||
OS_PROJECT_NAME
|
||||
OS_IDENTITY_API_VERSION
|
||||
OS_PASSWORD
|
||||
OS_AUTH_TYPE
|
||||
OS_AUTH_URL
|
||||
OS_USERNAME
|
||||
OS_ENDPOINT
|
||||
DEVSTACK_VENV
|
||||
VIRTUAL_ENV
|
||||
setenv = OS_RATING_API_VERSION=2
|
||||
commands = stestr run --concurrency=1 --test-path ./cloudkittyclient/tests/functional/v2
|
||||
|
||||
@@ -45,13 +74,15 @@ commands = flake8
|
||||
commands = {posargs}
|
||||
|
||||
[testenv:docs]
|
||||
deps = -r{toxinidir}/doc/requirements.txt
|
||||
deps =
|
||||
-c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/2024.1}
|
||||
-r{toxinidir}/doc/requirements.txt
|
||||
commands = sphinx-build --keep-going -b html doc/source doc/build/html
|
||||
|
||||
[testenv:pdf-docs]
|
||||
envdir = {toxworkdir}/docs
|
||||
deps = {[testenv:docs]deps}
|
||||
whitelist_externals =
|
||||
allowlist_externals =
|
||||
make
|
||||
commands =
|
||||
sphinx-build --keep-going -b latex doc/source doc/build/pdf
|
||||
@@ -70,13 +101,7 @@ import_exceptions = cloudkittyclient.i18n
|
||||
|
||||
[testenv:releasenotes]
|
||||
deps =
|
||||
-c{env:TOX_CONSTRAINTS_FILE:https://opendev.org/openstack/requirements/raw/branch/master/upper-constraints.txt}
|
||||
-c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/2024.1}
|
||||
-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
|
||||
|
||||
Reference in New Issue
Block a user