Compare commits

...

6 Commits
4.0.0 ... 2.0.1

Author SHA1 Message Date
Luka Peschke
37c6bb0c8b Fix the rating.get_quotation method
This updates the rating.get_quotation method of the client. Tests on this
method have been added.

Depends-On: https://review.openstack.org/#/c/648062/
Change-Id: Ie2de0162311c2d162c1573042187ac4e628bd966
(cherry picked from commit de96c61985)
2020-03-20 14:44:13 +01:00
OpenDev Sysadmins
1e0ed2f044 OpenDev Migration Patch
This commit was bulk generated and pushed by the OpenDev sysadmins
as a part of the Git hosting and code review systems migration
detailed in these mailing list posts:

http://lists.openstack.org/pipermail/openstack-discuss/2019-March/003603.html
http://lists.openstack.org/pipermail/openstack-discuss/2019-April/004920.html

Attempts have been made to correct repository namespaces and
hostnames based on simple pattern matching, but it's possible some
were updated incorrectly or missed entirely. Please reach out to us
via the contact information listed at https://opendev.org/ with any
questions you may have.
2019-04-19 19:42:57 +00:00
Luka Peschke
c1596862ae Fix "cloudkitty report tenant list" command
This fixes the "cloudkitty report tenant list": command, by transforming each
element of the list returned by CliTenantList's take_action method
into a tuple.

Change-Id: Iba1401b0cb4319a668d449139c8d20fc011cf178
Story: 2004149
Task: 27622
2018-10-23 13:41:43 +02:00
Doug Hellmann
56c5badada import zuul job settings from project-config
This is a mechanically generated patch to complete step 1 of moving
the zuul job settings out of project-config and into each project
repository.

Because there will be a separate patch on each branch, the branch
specifiers for branch-specific jobs have been removed.

Because this patch is generated by a script, there may be some
cosmetic changes to the layout of the YAML file(s) as the contents are
normalized.

See the python3-first goal document for details:
https://governance.openstack.org/tc/goals/stein/python3-first.html

Change-Id: I219503b8a87e4d9fde94cbb832134a16adaeb8c0
Story: #2002586
Task: #24289
2018-08-31 08:59:42 -04:00
97e2a29496 Update UPPER_CONSTRAINTS_FILE for stable/rocky
The new stable upper-constraints file is only available
after the openstack/requirements repository is branched.
This will happen around the RC1 timeframe.

Recheck and merge this change once the requirements
repository has been branched.

The CI system will work with this patch before the requirements
repository is branched because zuul configues the job to run
with a local copy of the file and defaults to the master branch.
However, accepting the patch will break the test configuration
on developers' local systems, so please wait until after the
requirements repository is branched to merge the patch.

Change-Id: If5fc68369bb8fc629e35e926008254e864100d6f
2018-08-08 22:09:55 +00:00
ce7aef7912 Update .gitreview for stable/rocky
Change-Id: I5739630144929ebfd1b0919d302cb23f0f03a1c2
2018-08-08 22:09:53 +00:00
9 changed files with 138 additions and 9 deletions

View File

@@ -1,4 +1,5 @@
[gerrit]
host=review.openstack.org
host=review.opendev.org
port=29418
project=openstack/python-cloudkittyclient.git
defaultbranch=stable/rocky

View File

@@ -18,15 +18,19 @@
- ^releasenotes/.*$
vars:
devstack_plugins:
cloudkitty: https://git.openstack.org/openstack/cloudkitty
cloudkitty: https://opendev.org/openstack/cloudkitty
devstack_services:
ck-api: true
horizon: false
tox_install_siblings: false
zuul_work_dir: src/git.openstack.org/openstack/python-cloudkittyclient
zuul_work_dir: src/opendev.org/openstack/python-cloudkittyclient
tox_envlist: functional
- project:
templates:
- openstack-python-jobs
- openstack-python35-jobs
- openstackclient-plugin-jobs
check:
jobs:
- cloudkittyclient-devstack-functional:
@@ -35,3 +39,6 @@
jobs:
- cloudkittyclient-devstack-functional:
voting: true
post:
jobs:
- openstack-tox-cover

View File

@@ -35,7 +35,7 @@ class BaseFunctionalTest(utils.BaseTestCase):
if p.returncode != 0:
raise RuntimeError('"{cmd}" returned {val}: {msg}'.format(
cmd=' '.join(cmd), val=p.returncode, msg=stderr))
return json.loads(stdout) if has_output else None
return json.loads(stdout.decode('ascii')) if has_output else None
def openstack(self, action,
flags='', params='', fmt='-f json', has_output=True):

View File

@@ -0,0 +1,48 @@
# Copyright 2019 Objectif Libre
#
# 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.
#
import decimal
from cloudkittyclient import exc
from cloudkittyclient.tests.unit.v1 import base
class TestRating(base.BaseAPIEndpointTestCase):
def test_quote_request(self):
res_data = [{'usage': {
'instance': [{
'vol': {'unit': 'undef', 'qty': '1'},
'rating': {'price': decimal.Decimal(1)},
'desc': {
'disk_total_display': 1,
'image_id': 'c43a3e7d-c4e6-45d6-8c8d-e2832a45bc0a',
'ram': 64,
'ephemeral': 0,
'vcpus': 1,
'source_type': 'image',
'disk_total': 1,
'flavor_id': '42',
'flavor': 'm1.nano',
'disk': 1,
'source_val': 'c43a3e7d-c4e6-45d6-8c8d-e2832a45bc0a'}
}]
}}]
self.rating.get_quotation(res_data=res_data)
self.api_client.post.assert_called_once_with(
'/v1/rating/quote/', json={'resources': res_data})
def test_get_quotation_no_res_data(self):
self.assertRaises(exc.ArgumentRequired, self.rating.get_quotation)

View File

@@ -0,0 +1,63 @@
# Copyright 2018 Objectif Libre
#
# 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.
#
import collections
import mock
from cloudkittyclient.tests.unit.v1 import base
from cloudkittyclient.v1 import report_cli
class TestReportCli(base.BaseAPIEndpointTestCase):
def test_report_tenant_list(self):
class DummyAPIClient(object):
def get_tenants(*args, **kwargs):
return ['ee530dfc-319a-438f-9d43-346cfef501d6',
'91743a9a-688b-4526-b568-7b501531176c',
'4468704c-972e-4cfd-a342-9b71c493b79b']
class ClientWrap(object):
report = DummyAPIClient()
class DummyParsedArgs(object):
def __init__(self):
self.begin = '2042-01-01T00:00:00'
self.end = '2042-12-01T00:00:00'
class DummyCliTenantList(report_cli.CliTenantList):
def __init__(self):
pass
def __get_client_from_osc(*args):
return ClientWrap()
parsed_args = DummyParsedArgs()
cli_class_instance = DummyCliTenantList()
with mock.patch('cloudkittyclient.utils.get_client_from_osc',
new=__get_client_from_osc):
# NOTE(peschk_l): self is only used used to get a client so just we
# just override __init__ in order to skip class instanciation. In
# python3 we could just have passed None
result = report_cli.CliTenantList.take_action(
cli_class_instance, parsed_args)
assert len(result) == 2
assert result[0] == ('Tenant ID', )
assert isinstance(result[1], collections.Iterable)
for res in result[1]:
assert isinstance(res, collections.Iterable)

View File

@@ -78,8 +78,10 @@ class RatingManager(base.BaseManager):
"""
if not kwargs.get('res_data', None):
raise exc.ArgumentRequired("'res_data' argument is required.")
url = self.get_url('quote')
return self.api_client.post(url, kwargs['res_data'])
url = self.get_url('quote', {})
body = {'resources': kwargs['res_data']}
return self.api_client.post(url, json=body).json()
class CliModuleGet(lister.Lister):

View File

@@ -114,8 +114,11 @@ class CliTenantList(lister.Lister):
raise exc.InvalidArgumentError(
'Invalid timestamp "{}"'.format(value))
client = utils.get_client_from_osc(self)
return (('Tenant ID', ),
(client.report.get_tenants(**vars(parsed_args)), ))
tenants = client.report.get_tenants(**vars(parsed_args))
output = []
for tenant in tenants:
output.append((tenant, ))
return (('Tenant ID', ), output)
def get_parser(self, prog_name):
parser = super(CliTenantList, self).get_parser(prog_name)

View File

@@ -0,0 +1,5 @@
---
fixes:
- |
The ``rating.get_quotation`` method of the client has been fixed: the json
body has been updated to match the API reference.

View File

@@ -5,7 +5,7 @@ skipsdist = True
[testenv]
usedevelop = True
install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} -U {opts} {packages}
install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/rocky} -U {opts} {packages}
setenv =
VIRTUAL_ENV={envdir}
deps = -r{toxinidir}/requirements.txt