Compare commits

..

20 Commits

Author SHA1 Message Date
Zuul
57d4563817 Merge "Fix the rating.get_quotation method" into stable/stein 2019-04-04 14:26:54 +00:00
Luka Peschke
b465e86703 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)
2019-04-04 12:59:33 +00:00
Luka Peschke
1724798fd7 Adding a python3 functional job
Change-Id: I3bb28edc9d62e8ea622e1061cbfb50168c217f24
(cherry picked from commit aeebd64928)
2019-04-04 12:59:27 +00:00
Luka Peschke
1ee30ec19c Asserting 'summary get' returns nothing in functional tests
Since no data is available in devstack in our functional test environment,
we make the assertion that 'summary get' returns nothing. This is prone to
update if more complete test scenarios are implemented.

Change-Id: Ic80e39f0d2a75882762ebd6a0dba46033c9fd7f4
(cherry picked from commit a7e687f740)
2019-04-04 10:26:36 +00:00
Luka Peschke
8b26d758c0 Fix releasenotes generation
Change-Id: Id72ea6407350bfccf7443bca9f4880d1324812c9
2019-03-27 09:48:47 +00:00
377172f39d Update UPPER_CONSTRAINTS_FILE for stable/stein
Update the URL to the upper-constraints file to point to the redirect
rule on releases.openstack.org so that anyone working on this branch
will switch to the correct upper-constraints list automatically when
the requirements repository branches.

Until the requirements repository has as stable/stein branch, tests will
continue to use the upper-constraints list on master.

Change-Id: Ibae1e8d8710efb9796f8e89547b994d4bf42c780
2019-03-18 14:49:53 +00:00
98e177260d Update .gitreview for stable/stein
Change-Id: Ic0fc80ffa4bdf16e9aa5b36a7be7614a74ee2d73
2019-03-18 14:49:50 +00:00
Zuul
3b49fbd4d0 Merge "Use global-requirements for requirements" 2018-10-26 11:13:37 +00:00
Luka Peschke
e9a92a2941 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 11:27:13 +02:00
Luka Peschke
1ed287c92a Use global-requirements for requirements
This updates cloudkittyclient's requirement files in order to use
openstack/requirements for constraints. This will help to avoid dependency
conflicts when cloudkittyclient is deployed in an openstack context.

Work items:

* Updated requirements.txt, test-requirements.txt and doc/requirements.txt
  with the `update-requirements` tool provided by openstack/requirements.

* Added a lower-constraints.txt file.

* Added the "check-requirements" zuul job template to the CI.

Change-Id: I12a882ce4d24ade153a64b75852396377ac42ca6
2018-10-22 18:10:19 +02:00
huang.zhiping
63ac84b165 Update min tox version to 2.0
The commands used by constraints need at least tox 2.0.  Update to
reflect reality, which should help with local running of constraints
targets.

Change-Id: I0ff800d84949f1a02b083b4fcf16e9b82f0d9e57
2018-10-21 02:00:40 +00:00
Vieri
1cf5b3aca2 Don't quote {posargs} in tox.ini
Quotes around {posargs} cause the entire string to be combined into one
arg that gets passed to stestr. This prevents passing multiple args
(e.g. '--concurrency=16 some-regex')

Change-Id: Ie33e01abfd695c100033ec1ede8f14fec98d4b36
2018-10-09 13:46:50 +00:00
Luka Peschke
503dd3247a Add documentation jobs
Currently, the client's docs are neither built nor published. This
adds the required jobs.

Change-Id: I4199b6091502c22bf2a718d5baec29ab3f2ec400
2018-09-20 13:40:43 +02:00
Andreas Jaeger
7b9d447eb8 Use openstack-tox-cover template
Use openstack-tox-cover template, this runs the cover job as
non-voting in the check queue only.

Remove jobs and use template instead.

Add cover tox.ini environment - this job never worked before.

Change-Id: I9652aed41bc21bafc10e8c4a046d52bfb9681bdc
2018-09-07 14:32:43 +02:00
Zuul
a9eb87c436 Merge "Add `insecure and cacert` options to the client." 2018-09-07 10:00:10 +00:00
Luka Peschke
fff37a84fa Add `insecure and cacert` options to the client.
The client does support SSL authentication through keystoneauth right now. In
CLI mode, this is done through the "--os-cert" and "--os-cacert" options, or
through environment variables.

However, when the client is used as a python library,this is done through
requests' "verify" parameter, which is not very explicit.

This adds two parameters to the client

Change-Id: I68969c658724f53c85c47ab6098a3e2165f5925d
Story: 2003689
Task: 26224
2018-09-06 20:50:59 +02:00
Matthias Bastian
81cdcba4f3 Consider interface and region options with OSC
The --os-interface/OS_INTERFACE and --os-region-name/OS_REGION_NAME
options were considered by cloudkitty CLI but ignored when using the OSC
integration.

Change-Id: I36dc3616fba59c9b2e77da75abe0f76db7ddb7e4
2018-09-06 12:35:59 +02:00
Doug Hellmann
214083c695 add python 3.6 unit test job
This is a mechanically generated patch to add a unit test job running
under Python 3.6 as part of the python3-first goal.

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

Change-Id: I257a223e215cfb383f600954e612ffd92ab1b6f8
Story: #2002586
Task: #24289
2018-08-31 08:57:48 -04:00
Doug Hellmann
c78ae05005 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: I0fc887efcc4196dd3b371b2edae44075eb0b845e
Story: #2002586
Task: #24289
2018-08-31 08:57:42 -04:00
1348fd67e1 Update reno for stable/rocky
Change-Id: Ie70f71c1b702fd77039b4249c3ba562d0b813095
2018-08-08 22:09:57 +00:00
19 changed files with 244 additions and 32 deletions

View File

@@ -2,3 +2,4 @@
host=review.openstack.org
port=29418
project=openstack/python-cloudkittyclient.git
defaultbranch=stable/stein

View File

@@ -19,6 +19,8 @@
vars:
devstack_plugins:
cloudkitty: https://git.openstack.org/openstack/cloudkitty
devstack_localrc:
CLOUDKITTY_FETCHER: keystone
devstack_services:
ck-api: true
horizon: false
@@ -26,12 +28,34 @@
zuul_work_dir: src/git.openstack.org/openstack/python-cloudkittyclient
tox_envlist: functional
- job:
name: cloudkittyclient-devstack-functional-py3
parent: cloudkittyclient-devstack-functional
description: |
Job for cloudkittyclient functional tests, ran in python3.
vars:
devstack_localrc:
DEVSTACK_GATE_USE_PYTHON3: "True"
USE_PYTHON3: "True"
- project:
templates:
- check-requirements
- openstack-cover-jobs
- openstack-python-jobs
- openstack-python35-jobs
- openstack-python36-jobs
- openstackclient-plugin-jobs
- publish-openstack-docs-pti
check:
jobs:
- cloudkittyclient-devstack-functional:
voting: true
- cloudkittyclient-devstack-functional-py3:
voting: true
gate:
jobs:
- cloudkittyclient-devstack-functional:
voting: true
- cloudkittyclient-devstack-functional-py3:
voting: true

View File

@@ -30,7 +30,12 @@ def make_client(instance):
version,
API_VERSIONS)
instance.setup_auth()
return ck_client(session=instance.session)
adapter_options = dict(
interface=instance.interface,
region_name=instance.region_name,
)
return ck_client(session=instance.session,
adapter_options=adapter_options)
def build_option_parser(parser):

View File

@@ -22,8 +22,8 @@ class CkReportTest(base.BaseFunctionalTest):
self.runner = self.cloudkitty
def test_get_summary(self):
resp = self.runner('summary get')[0]
self.assertEqual(resp['Resource Type'], 'ALL')
resp = self.runner('summary get')
self.assertEqual(len(resp), 0)
def test_get_summary_with_groupby(self):
resp = self.runner('summary get', params='-g res_type tenant_id')

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

@@ -25,12 +25,26 @@ from cloudkittyclient.v1 import storage
class Client(object):
def __init__(self, session=None, adapter_options={}, **kwargs):
def __init__(self,
session=None,
adapter_options={},
cacert=None,
insecure=False,
**kwargs):
adapter_options.setdefault('service_type', 'rating')
if insecure:
verify_cert = False
else:
if cacert:
verify_cert = cacert
else:
verify_cert = True
self.session = session
if self.session is None:
self.session = ks_session.Session(**kwargs)
self.session = ks_session.Session(
verify=verify_cert, **kwargs)
self.api_client = adapter.Adapter(
session=self.session, **adapter_options)

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

@@ -3,5 +3,5 @@
# process, which may cause wedges in the gate later.
openstackdocstheme>=1.18.1 # Apache-2.0
sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD
reno>=2.5.0 # Apache2
sphinx>=1.6.2,!=1.6.6,!=1.6.7 # BSD
reno>=2.5.0 # Apache-2.0

View File

@@ -49,6 +49,16 @@ Else, use it the same way as any other OpenStack client::
u'res_type': u'ALL',
u'tenant_id': u'bea6a24f77e946b0a92dca7c78b7870b'}]}
.. warning::
If you want to use SSL with the client as a python library, you need to
provide a cert to keystone's session object. Else, two additional options
are available if you provide an ``auth`` object to the client: ``insecure``
and ``cacert``::
>>> client = ck_client.Client(
'1', auth=auth, insecure=False, cacert='/path/to/ca')
When using the ``cloudkitty`` CLI client with keystone authentication, the
auth plugin to use should automagically be detected. If not, you can specify
the auth plugin to use with ``--os-auth-type/--os-auth-plugin``::

23
lower-constraints.txt Normal file
View File

@@ -0,0 +1,23 @@
# requirements
pbr==2.0.0 # Apache-2.0
cliff==2.11.0 # Apache-2.0
keystoneauth1==3.4.0 # Apache-2.0
oslo.utils==3.35 # Apache-2.0
oslo.log==3.36 # Apache-2.0
PyYAML==3.12 # MIT
jsonpath-rw-ext==1.0 # Apache-2.0
six==1.11 # MIT
os-client-config==1.29.0 # Apache-2.0
# test-requirements.txt
coverage==4.0 # Apache-2.0
python-subunit==0.0.18 # Apache-2.0/BSD
oslotest==1.10.0 # Apache-2.0
stestr==2.0 # Apache-2.0
mock==2.0 # BSD
python-openstackclient==3.14 # Apache-2.0
# doc/requirements.txt
openstackdocstheme==1.18.1 # Apache-2.0
sphinx==1.6.2 # BSD
reno==2.5.0 # Apache2

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

@@ -16,7 +16,6 @@
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
import pbr.version
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
@@ -26,8 +25,8 @@ import pbr.version
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'oslosphinx',
'reno.sphinxext',
'openstackdocstheme',
]
# Add any paths that contain templates here, relative to this directory.
@@ -46,16 +45,12 @@ master_doc = 'index'
project = u'Cloudkitty Client Release Notes'
copyright = u'2016, Cloudkitty developers'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
cloudkittyclient_version = pbr.version.VersionInfo('python-cloudkittyclient')
# Release notes are version independent.
# The short X.Y version.
version = cloudkittyclient_version.canonical_version_string()
version = ''
# The full version, including alpha/beta/rc tags.
release = cloudkittyclient_version.version_string_with_vcs()
release = ''
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -100,7 +95,7 @@ pygments_style = 'sphinx'
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
html_theme = 'openstackdocs'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the

View File

@@ -8,6 +8,7 @@ Contents
:maxdepth: 2
unreleased
rocky
queens
Indices and tables

View File

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

View File

@@ -2,12 +2,12 @@
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
pbr!=2.1.0,>=2.0.0 # Apache-2.0
cliff>=2.11.0,<3.0 # Apache-2.0
keystoneauth1>=3.4.0,<4.0 # Apache-2.0
oslo.utils>=3.35,<4.0 # Apache-2.0
oslo.log>=3.36,<4.0 # Apache-2.0
PyYAML>=3.12,<4.0 # MIT
pbr>=2.0.0,!=2.1.0 # Apache-2.0
cliff>=2.11.0 # Apache-2.0
keystoneauth1>=3.4.0 # Apache-2.0
oslo.utils>=3.35 # Apache-2.0
oslo.log>=3.36 # Apache-2.0
PyYAML>=3.12 # MIT
jsonpath-rw-ext>=1.0 # Apache-2.0
six>=1.11,<2.0 # MIT
six>=1.11 # MIT
os-client-config>=1.29.0 # Apache-2.0

View File

@@ -4,7 +4,7 @@
hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
coverage!=4.4,>=4.0 # Apache-2.0
coverage>=4.0,!=4.4 # Apache-2.0
python-subunit>=0.0.18 # Apache-2.0/BSD
oslotest>=1.10.0 # Apache-2.0
stestr>=2.0 # Apache-2.0

16
tox.ini
View File

@@ -1,17 +1,29 @@
[tox]
minversion = 1.6
minversion = 2.0
envlist = py35,py27,pypy,pep8
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://releases.openstack.org/constraints/upper/stein} -U {opts} {packages}
setenv =
VIRTUAL_ENV={envdir}
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands = stestr run {posargs}
[testenv:cover]
basepython = python3
setenv =
VIRTUAL_ENV={envdir}
PYTHON=coverage run --source cloudkittyclient --parallel-mode
commands =
stestr run {posargs}
coverage combine
coverage html -d cover
coverage xml -o cover/coverage.xml
coverage report
[testenv:debug]
basepython = python3
commands = oslo_debug_helper {posargs}