Compare commits

...

23 Commits

Author SHA1 Message Date
OpenDev Sysadmins
0418fcbad9 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
Doug Hellmann
e6c3d5b48b Update .gitreview for stable/newton
Change-Id: I6532f4374b09d5e58758045ceb976b3f65d89613
2016-09-02 09:41:25 -04:00
zhangguoqing
b24e261143 Fix the logic of do_hashmap_mapping_list
Only give the group_id should be allowed to do_hashmap_mapping_list,
and add the corresponding test case.

Depends-On: I4fe27a07e369728396d440b6b2f3462ee74d5f4d
Change-Id: Ia4272fff33b70db0dc24f7bf0a6d5971504cee7a
2016-09-01 16:01:11 +00:00
zhangguoqing
9acc36b4ca Add short arg for collector command
Change-Id: I92a9e03c6c8c517a78d03670ca19c3da54a4e3f2
2016-09-01 21:03:30 +08:00
Maxime Cottret
a6093c5a36 Fix CLI threshold command
- Threshold commands now use 'type' API field instead of 'map_type'
- change CLI option from "-m, --map-type" to "-t, --type" (same as mapping commands option)
- change short option for threshold-id to "-i"

Change-Id: I8c0f6b135bdc206ce1fc3ea14debd8d2cafc9ea7
Closes-Bug: #1619150
2016-09-01 11:15:56 +02:00
Jenkins
9554c9e440 Merge "Replaces client_kwargs by empty dict in ckclient/shell.py" 2016-08-29 10:20:59 +00:00
Luka Peschke
8318891835 Replaces client_kwargs by empty dict in ckclient/shell.py
ckclient.get_client() doesn't need the command-line args.

The client_kwargs.update() altered the args, and caused the project_id
field to be overwritten, leading to an invalid http request in
some cases.

Closes-Bug: #1616805
Change-Id: I09fe3bc3c71a399bdcfaaa178543a2516494399b
2016-08-25 15:54:57 +02:00
Maxime Cottret
b2a42f71fe Fix CLI auth user interface
This patch fixes how auth options are checked in CLI.

Use either:
- tenant-id or tenant-name
- project-id and user-domain (id or name)
- project-name and project-domain (id or name) and user-domain (id or name)

For consistency, the same checking is used in the client authentication plugin.

Change-Id: I2210d8bf21bba5d1faf72dfbe38756078d8bc0c1
Closes-Bug: #1616468
2016-08-25 10:11:09 +02:00
Jenkins
1d8378cc6c Merge "Removes MANIFEST.in as it is not needed explicitely by PBR" 2016-08-08 12:48:45 +00:00
Jenkins
44a2bb0b26 Merge "Support getting client with keystone session" 2016-08-08 12:48:40 +00:00
Jenkins
0417e30f76 Merge "Remove discover from test-requirements" 2016-08-08 12:43:23 +00:00
zhangguoqing
a4dd6e1a61 [trivial] fix wrong typo
group_id --> tenant_id

Change-Id: Iaf3d3b4f83ae7007d3bda1f9adade881a298c7ec
2016-08-06 05:15:01 +00:00
Jenkins
d503c98cbe Merge "Fix client V3 unscope bug" 2016-08-02 13:16:16 +00:00
Swapnil Kulkarni (coolsvap)
0efe6a0606 Remove discover from test-requirements
It's only needed for python < 2.7 which is not supported

Change-Id: Ic92b43c09a0f8e4892b4fdd2b91c00e839e7adec
2016-07-22 03:52:26 +00:00
Jenkins
69399b5e5d Merge "Add client support for per tenant hashmap rules" 2016-06-30 16:01:19 +00:00
Jenkins
df5087a344 Merge "[Trivial] Remove executable privilege of doc/source/conf.py" 2016-06-23 15:34:04 +00:00
Stéphane Albert
70771bf2d7 Add client support for per tenant hashmap rules
Change-Id: Id85a0de7115439131cef4d1a98f884c2334fc474
2016-06-15 04:47:12 +00:00
Gauvain Pocentek
367608ceeb Remove spec file since cloudkittyclient is in RDO
Change-Id: I7cfa01daf2a6aa64bbf9afb89e817ff9d3942c71
2016-06-15 06:46:13 +02:00
Gauvain Pocentek
92981a7bb4 Add an explicit dependency on prettytable
Update the requirements for neutron

Change-Id: I0237bc725c6ab1948b40218a01434440dd173e8c
2016-06-14 16:24:59 +02:00
ZhiQiang Fan
5faa8b0de6 [Trivial] Remove executable privilege of doc/source/conf.py
It is a configuration file, rather than a script.

Change-Id: I133c05be7de743d2a89a69ef100ebe5d43422cd9
2016-04-29 20:19:29 +08:00
Chaozhe.Chen
066c9564fb Fix client V3 unscope bug
Client V3 will get unscope auth as no project provided. Unscope auth
will make client get empty catalog back from keystone.

This backport from ceilometer-client patch[1] and I verified it in my
devstack.

[1]https://review.openstack.org/#/c/169409/

Change-Id: I1fa5a5b1e9a40501dfbd563bf608d41eb4879bf8
Closes-Bug: #1522728
2016-02-16 17:02:11 +08:00
sonu.kumar
4dc3e65e44 Removes MANIFEST.in as it is not needed explicitely by PBR
This patch removes `MANIFEST.in` file as pbr generates a sensible
manifest from git files and some standard files and it removes
the need for an explicit `MANIFEST.in` file.

Change-Id: Iddbd1a4b574223d840707351c5e8f025d56f2046
2015-12-17 14:45:11 +05:30
Chaozhe.Chen
df4e8360e2 Support getting client with keystone session
This change will allow cloudkitty client to use keystoneclient/
keystoneauth session object.

Change-Id: Icc4bf5da12fb24d189fc38daf1b5cfb4a43228aa
2015-12-10 01:30:50 +08:00
13 changed files with 250 additions and 117 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/newton

View File

@@ -1,6 +0,0 @@
include AUTHORS
include ChangeLog
exclude .gitignore
exclude .gitreview
global-exclude *.pyc

View File

@@ -10,6 +10,10 @@
# License for the specific language governing permissions and limitations
# under the License.
import contextlib
import time
from keystoneclient import adapter
from keystoneclient.auth.identity import v2 as v2_auth
from keystoneclient.auth.identity import v3 as v3_auth
from keystoneclient import discover
@@ -21,6 +25,7 @@ import six.moves.urllib.parse as urlparse
from cloudkittyclient.common import utils
from cloudkittyclient import exc
from cloudkittyclient.openstack.common.apiclient import auth
from cloudkittyclient.openstack.common.apiclient import client
from cloudkittyclient.openstack.common.apiclient import exceptions
@@ -203,8 +208,13 @@ class AuthPlugin(auth.BaseAuthPlugin):
"""
has_token = self.opts.get('token') or self.opts.get('auth_token')
no_auth = has_token and self.opts.get('endpoint')
has_project = (self.opts.get('project_id')
or (self.opts.get('project_name')
and (self.opts.get('user_domain_name')
or self.opts.get('user_domain_id'))))
has_tenant = self.opts.get('tenant_id') or self.opts.get('tenant_name')
has_credential = (self.opts.get('username') and has_tenant
has_credential = (self.opts.get('username')
and (has_project or has_tenant)
and self.opts.get('password')
and self.opts.get('auth_url'))
missing = not (no_auth or has_credential)
@@ -253,9 +263,28 @@ def get_client(version, **kwargs):
:param api_version: the API version to use ('1')
:param kwargs: keyword args containing credentials, either:
* session: a keystoneauth/keystoneclient session object
* service_type: The default service_type for URL discovery
* service_name: The default service_name for URL discovery
* interface: The default interface for URL discovery
(Default: public)
* region_name: The default region_name for URL discovery
* endpoint_override: Always use this endpoint URL for requests
for this cloudkittyclient
* auth: An auth plugin to use instead of the session one
* user_agent: The User-Agent string to set
(Default is python-cloudkittyclient)
* connect_retries: the maximum number of retries that should be
attempted for connection errors
* logger: A logging object
or (DEPRECATED):
* os_token: pre-existing token to re-use
* os_endpoint: Cloudkitty API endpoint
or:
or (DEPRECATED):
* os_username: name of user
* os_password: user's password
* os_user_id: user's id
@@ -317,3 +346,87 @@ def get_auth_plugin(endpoint, **kwargs):
project_domain_id=kwargs.get('project_domain_id')
)
return auth_plugin
LEGACY_OPTS = ('auth_plugin', 'auth_url', 'token', 'insecure', 'cacert',
'tenant_id', 'project_id', 'username', 'password',
'project_name', 'tenant_name',
'user_domain_name', 'user_domain_id',
'project_domain_name', 'project_domain_id',
'key_file', 'cert_file', 'verify', 'timeout', 'cert')
def construct_http_client(**kwargs):
kwargs = kwargs.copy()
if kwargs.get('session') is not None:
# Drop legacy options
for opt in LEGACY_OPTS:
kwargs.pop(opt, None)
return SessionClient(
session=kwargs.pop('session'),
service_type=kwargs.pop('service_type', 'rating') or 'rating',
interface=kwargs.pop('interface', kwargs.pop('endpoint_type',
'publicURL')),
region_name=kwargs.pop('region_name', None),
user_agent=kwargs.pop('user_agent', 'python-cloudkittyclient'),
auth=kwargs.get('auth', None),
timings=kwargs.pop('timings', None),
**kwargs)
else:
return client.BaseClient(client.HTTPClient(
auth_plugin=kwargs.get('auth_plugin'),
region_name=kwargs.get('region_name'),
endpoint_type=kwargs.get('endpoint_type'),
original_ip=kwargs.get('original_ip'),
verify=kwargs.get('verify'),
cert=kwargs.get('cert'),
timeout=kwargs.get('timeout'),
timings=kwargs.get('timings'),
keyring_saver=kwargs.get('keyring_saver'),
debug=kwargs.get('debug'),
user_agent=kwargs.get('user_agent'),
http=kwargs.get('http')
))
@contextlib.contextmanager
def record_time(times, enabled, *args):
"""Record the time of a specific action.
:param times: A list of tuples holds time data.
:type times: list
:param enabled: Whether timing is enabled.
:type enabled: bool
:param args: Other data to be stored besides time data, these args
will be joined to a string.
"""
if not enabled:
yield
else:
start = time.time()
yield
end = time.time()
times.append((' '.join(args), start, end))
class SessionClient(adapter.LegacyJsonAdapter):
def __init__(self, *args, **kwargs):
self.times = []
self.timings = kwargs.pop('timings', False)
super(SessionClient, self).__init__(*args, **kwargs)
def request(self, url, method, **kwargs):
kwargs.setdefault('headers', kwargs.get('headers', {}))
# NOTE(sileht): The standard call raises errors from
# keystoneauth, where we need to raise the cloudkittyclient errors.
raise_exc = kwargs.pop('raise_exc', True)
with record_time(self.times, self.timings, method, url):
resp, body = super(SessionClient, self).request(url,
method,
raise_exc=False,
**kwargs)
if raise_exc and resp.status_code >= 400:
raise exc.from_response(resp, body)
return resp

View File

@@ -198,12 +198,11 @@ class CloudkittyShell(object):
@staticmethod
def no_project_and_domain_set(args):
if not (args.os_project_id or (args.os_project_name and
(args.os_user_domain_name or args.os_user_domain_id)) or
(args.os_tenant_id or args.os_tenant_name)):
return True
else:
return False
return not (((args.os_project_id or (args.os_project_name and
(args.os_project_domain_name or
args.os_project_domain_id)))
and (args.os_user_domain_name or args.os_user_domain_id))
or (args.os_tenant_id or args.os_tenant_name))
def main(self, argv):
parsed = self.parse_args(argv)
@@ -242,20 +241,24 @@ class CloudkittyShell(object):
"env[OS_USER_DOMAIN_NAME] or "
"a domain_id via either "
"--os-user-domain-id or via "
"env[OS_USER_DOMAIN_ID]")
if not (self.auth_plugin.opts['tenant_id']
or self.auth_plugin.opts['tenant_name']):
raise exc.CommandError("You must provide a tenant_id via "
"either --os-tenant-id or via "
"env[OS_TENANT_ID]")
"env[OS_USER_DOMAIN_ID]\n\n"
"As an alternative to project_id, "
"you can provide a project_name via "
"either --os-project-name or via "
"env[OS_PROJECT_NAME] and "
"a project_domain_name via either "
"--os-project-domain-name or via "
"env[OS_PROJECT_DOMAIN_NAME] or "
"a project_domain_id via either "
"--os-project-domain-id or via "
"env[OS_PROJECT_DOMAIN_ID]")
if not self.auth_plugin.opts['auth_url']:
raise exc.CommandError("You must provide an auth url via "
"either --os-auth-url or via "
"env[OS_AUTH_URL]")
client_kwargs = vars(args)
client_kwargs = {}
client_kwargs.update(self.auth_plugin.opts)
client_kwargs['auth_plugin'] = self.auth_plugin
client = ckclient.get_client(api_version, **client_kwargs)

View File

@@ -45,6 +45,16 @@ class ClientTest(utils.BaseTestCase):
def setUp(self):
super(ClientTest, self).setUp()
def test_client_v1_with_session(self):
resp = mock.Mock(status_code=200, text=b'')
resp.json.return_value = {"modules": []}
session = mock.Mock()
session.request.return_value = resp
c = client.get_client(1, session=session)
c.modules.list()
self.assertTrue(session.request.called)
self.assertTrue(resp.json.called)
def test_client_version(self):
c1 = self.create_client(env=FAKE_ENV, api_version=1)
self.assertIsInstance(c1, v1client.Client)
@@ -137,7 +147,8 @@ class ClientTest(utils.BaseTestCase):
env = FAKE_ENV.copy()
env['cacert'] = '/path/to/cacert'
client = self.create_client(env)
self.assertEqual('/path/to/cacert', client.client.verify)
self.assertEqual('/path/to/cacert',
client.http_client.http_client.verify)
def test_v1_client_certfile_and_keyfile(self):
env = FAKE_ENV.copy()
@@ -145,4 +156,4 @@ class ClientTest(utils.BaseTestCase):
env['key_file'] = '/path/to/keycert'
client = self.create_client(env)
self.assertEqual(('/path/to/cert', '/path/to/keycert'),
client.client.cert)
client.http_client.http_client.cert)

View File

@@ -622,6 +622,21 @@ class MappingManagerTest(utils.BaseTestCase):
self.api = client.BaseClient(self.http_client)
self.mgr = hashmap.MappingManager(self.api)
def test_get_mappings_by_group(self):
mappings = self.mgr.findall(group_id=GROUP2['group_id'])
expect = [
'GET', ('/v1/rating/module_config/hashmap/mappings?group_id=' +
GROUP2['group_id'])]
self.http_client.assert_called(*expect)
self.assertEqual(1, len(mappings))
mapping = mappings[0]
self.assertEqual(FIELD1['field_id'], mapping.field_id)
self.assertEqual(FIELD_MAPPING1['group_id'], mapping.group_id)
self.assertEqual(FIELD_MAPPING1['mapping_id'], mapping.mapping_id)
self.assertEqual(FIELD_MAPPING1['value'], mapping.value)
self.assertEqual(FIELD_MAPPING1['cost'], mapping.cost)
self.assertEqual(FIELD_MAPPING1['type'], mapping.type)
def test_get_a_mapping(self):
resource = self.mgr.get(mapping_id=FIELD_MAPPING1['mapping_id'])
expect = [
@@ -700,6 +715,27 @@ class ThresholdManagerTest(utils.BaseTestCase):
self.api = client.BaseClient(self.http_client)
self.mgr = hashmap.ThresholdManager(self.api)
def test_get_thresholds_by_group(self):
mappings = self.mgr.findall(group_id=GROUP3['group_id'])
expect = [
'GET', ('/v1/rating/module_config/hashmap/thresholds?group_id=' +
GROUP3['group_id'])]
self.http_client.assert_called(*expect)
self.assertEqual(1, len(mappings))
mapping = mappings[0]
self.assertEqual(SERVICE_THRESHOLD1['threshold_id'],
mapping.threshold_id)
self.assertEqual(SERVICE_THRESHOLD1['service_id'],
mapping.service_id)
self.assertEqual(SERVICE_THRESHOLD1['group_id'],
mapping.group_id)
self.assertEqual(SERVICE_THRESHOLD1['level'],
mapping.level)
self.assertEqual(SERVICE_THRESHOLD1['cost'],
mapping.cost)
self.assertEqual(SERVICE_THRESHOLD1['map_type'],
mapping.map_type)
def test_get_a_threshold(self):
resource = self.mgr.get(
threshold_id=SERVICE_THRESHOLD1['threshold_id'])

View File

@@ -16,7 +16,6 @@
from stevedore import extension
from cloudkittyclient import client as ckclient
from cloudkittyclient.openstack.common.apiclient import client
from cloudkittyclient.v1 import collector
from cloudkittyclient.v1 import core
from cloudkittyclient.v1 import report
@@ -28,33 +27,33 @@ SUBMODULES_NAMESPACE = 'cloudkitty.client.modules'
class Client(object):
"""Client for the Cloudkitty v1 API.
:param string endpoint: A user-supplied endpoint URL for the cloudkitty
service.
:param function token: Provides token for authentication.
:param integer timeout: Allows customization of the timeout for client
http requests. (optional)
:param session: a keystoneauth/keystoneclient session object
:type session: keystoneclient.session.Session
:param str service_type: The default service_type for URL discovery
:param str service_name: The default service_name for URL discovery
:param str interface: The default interface for URL discovery
(Default: public)
:param str region_name: The default region_name for URL discovery
:param str endpoint_override: Always use this endpoint URL for requests
for this cloudkittyclient
:param auth: An auth plugin to use instead of the session one
:type auth: keystoneclient.auth.base.BaseAuthPlugin
:param str user_agent: The User-Agent string to set
(Default is python-cloudkittyclient)
:param int connect_retries: the maximum number of retries that should be
attempted for connection errors
:param logger: A logging object
:type logger: logging.Logger
"""
def __init__(self, *args, **kwargs):
"""Initialize a new client for the Cloudkitty v1 API."""
self.auth_plugin = (kwargs.get('auth_plugin')
or ckclient.get_auth_plugin(*args, **kwargs))
self.client = client.HTTPClient(
auth_plugin=self.auth_plugin,
region_name=kwargs.get('region_name'),
endpoint_type=kwargs.get('endpoint_type'),
original_ip=kwargs.get('original_ip'),
verify=kwargs.get('verify'),
cert=kwargs.get('cert'),
timeout=kwargs.get('timeout'),
timings=kwargs.get('timings'),
keyring_saver=kwargs.get('keyring_saver'),
debug=kwargs.get('debug'),
user_agent=kwargs.get('user_agent'),
http=kwargs.get('http')
)
self.http_client = client.BaseClient(self.client)
if not kwargs.get('auth_plugin'):
kwargs['auth_plugin'] = ckclient.get_auth_plugin(*args, **kwargs)
self.auth_plugin = kwargs.get('auth_plugin')
self.http_client = ckclient.construct_http_client(**kwargs)
self.modules = core.CloudkittyModuleManager(self.http_client)
self.collector = collector.CollectorManager(self.http_client)
self.reports = report.ReportManager(self.http_client)

View File

@@ -17,7 +17,7 @@
from cloudkittyclient.common import utils
@utils.arg('--collector',
@utils.arg('-c', '--collector',
help='Collector name to filter on.',
required=False,
default=None)
@@ -29,7 +29,7 @@ def do_collector_mapping_list(cc, args):
utils.print_list(data, fields, fields_labels, sortby=0)
@utils.arg('--service',
@utils.arg('-s', '--service',
help='Which service to get the mapping for.',
required=True)
def do_collector_mapping_get(cc, args):
@@ -38,10 +38,10 @@ def do_collector_mapping_get(cc, args):
utils.print_dict(data.to_dict())
@utils.arg('--collector',
@utils.arg('-c', '--collector',
help='Map a service to this collector.',
required=True)
@utils.arg('--service',
@utils.arg('-s', '--service',
help='Map a collector to this service.',
required=True)
def do_collector_mapping_create(cc, args):
@@ -51,7 +51,7 @@ def do_collector_mapping_create(cc, args):
utils.print_dict(out.to_dict())
@utils.arg('--service',
@utils.arg('-s', '--service',
help='Filter on this service.',
required=True)
def do_collector_mapping_delete(cc, args):
@@ -60,7 +60,7 @@ def do_collector_mapping_delete(cc, args):
cc.collector.mappings.delete(mapping_id=args.service)
@utils.arg('--name',
@utils.arg('-n', '--name',
help='Name of the collector.',
required=True)
def do_collector_state_get(cc, args):
@@ -69,7 +69,7 @@ def do_collector_state_get(cc, args):
utils.print_dict(data.to_dict())
@utils.arg('--name',
@utils.arg('-n', '--name',
help='Name of the collector.',
required=True)
def do_collector_state_enable(cc, args):
@@ -78,7 +78,7 @@ def do_collector_state_enable(cc, args):
utils.print_dict(new_state.to_dict())
@utils.arg('--name',
@utils.arg('-n', '--name',
help='Name of the collector.',
required=True)
def do_collector_state_disable(cc, args):

View File

@@ -126,6 +126,9 @@ def common_hashmap_mapping_arguments(create=False):
@utils.arg('-g', '--group-id',
help='Group id',
required=False)
@utils.arg('-p', '--project-id',
help='Project/tenant id',
required=False)
@functools.wraps(func)
def _wrapped(*args, **kwargs):
return func(*args, **kwargs)
@@ -149,6 +152,7 @@ def do_hashmap_mapping_create(cc, args={}):
'service_id': 'service_id',
'field_id': 'field_id',
'group_id': 'group_id',
'project_id': 'tenant_id',
}
fields = {}
for k, v in vars(args).items():
@@ -171,6 +175,7 @@ def do_hashmap_mapping_update(cc, args={}):
'value': 'value',
'type': 'type',
'group_id': 'group_id',
'project_id': 'tenant_id',
}
try:
mapping = cc.hashmap.mappings.get(mapping_id=args.mapping_id)
@@ -192,10 +197,15 @@ def do_hashmap_mapping_update(cc, args={}):
@utils.arg('-g', '--group-id',
help='Group id',
required=False)
@utils.arg('-p', '--project-id',
help='Project/tenant id',
required=False)
def do_hashmap_mapping_list(cc, args={}):
"""List mappings."""
if args.service_id is None and args.field_id is None:
raise exc.CommandError("Provide either service-id or field-id")
if (args.group_id is None and
args.service_id is None and args.field_id is None):
raise exc.CommandError("Provide either group-id, service-id or "
"field-id")
try:
mappings = cc.hashmap.mappings.list(service_id=args.service_id,
field_id=args.field_id,
@@ -205,10 +215,10 @@ def do_hashmap_mapping_list(cc, args={}):
else:
field_labels = ['Mapping id', 'Value', 'Cost',
'Type', 'Field id',
'Service id', 'Group id']
'Service id', 'Group id', 'Tenant id']
fields = ['mapping_id', 'value', 'cost',
'type', 'field_id',
'service_id', 'group_id']
'service_id', 'group_id', 'tenant_id']
utils.print_list(mappings, fields, field_labels,
sortby=0)
@@ -279,12 +289,15 @@ def common_hashmap_threshold_arguments(create=False):
@utils.arg('-c', '--cost',
help='Threshold cost',
required=create)
@utils.arg('-m', '--map-type',
@utils.arg('-t', '--type',
help='Threshold type (flat, rate)',
required=False)
@utils.arg('-g', '--group-id',
help='Group id',
required=False)
@utils.arg('-p', '--project-id',
help='Project/tenant id',
required=False)
@functools.wraps(func)
def _wrapped(*args, **kwargs):
return func(*args, **kwargs)
@@ -304,10 +317,11 @@ def do_hashmap_threshold_create(cc, args={}):
arg_to_field_mapping = {
'level': 'level',
'cost': 'cost',
'map_type': 'map_type',
'type': 'type',
'service_id': 'service_id',
'field_id': 'field_id',
'group_id': 'group_id',
'project_id': 'tenant_id',
}
fields = {}
for k, v in vars(args).items():
@@ -318,7 +332,7 @@ def do_hashmap_threshold_create(cc, args={}):
utils.print_dict(out.to_dict())
@utils.arg('-t', '--threshold-id',
@utils.arg('-i', '--threshold-id',
help='Threshold id',
required=True)
@common_hashmap_threshold_arguments()
@@ -328,8 +342,9 @@ def do_hashmap_threshold_update(cc, args={}):
'threshold_id': 'threshold_id',
'cost': 'cost',
'level': 'level',
'map_type': 'map_type',
'type': 'type',
'group_id': 'group_id',
'project_id': 'tenant_id',
}
try:
threshold = cc.hashmap.thresholds.get(threshold_id=args.threshold_id)
@@ -355,6 +370,9 @@ def do_hashmap_threshold_update(cc, args={}):
type=_bool_strict, metavar='{True,False}',
help='If True, list only orhpaned thresholds',
required=False)
@utils.arg('-p', '--project-id',
help='Project/tenant id',
required=False)
def do_hashmap_threshold_list(cc, args={}):
"""List thresholds."""
if (args.group_id is None and
@@ -371,14 +389,14 @@ def do_hashmap_threshold_list(cc, args={}):
else:
field_labels = ['Threshold id', 'Level', 'Cost',
'Type', 'Field id',
'Service id', 'Group id']
'Service id', 'Group id', 'Tenant id']
fields = ['threshold_id', 'level', 'cost',
'map_type', 'field_id',
'service_id', 'group_id']
'type', 'field_id',
'service_id', 'group_id', 'tenant_id']
utils.print_list(thresholds, fields, field_labels, sortby=0)
@utils.arg('-t', '--threshold-id',
@utils.arg('-i', '--threshold-id',
help='Threshold uuid',
required=True)
def do_hashmap_threshold_delete(cc, args={}):
@@ -389,7 +407,7 @@ def do_hashmap_threshold_delete(cc, args={}):
raise exc.CommandError('Threshold not found: %s' % args.threshold_id)
@utils.arg('-t', '--threshold-id',
@utils.arg('-i', '--threshold-id',
help='Threshold uuid',
required=True)
def do_hashmap_threshold_get(cc, args={}):
@@ -401,7 +419,7 @@ def do_hashmap_threshold_get(cc, args={}):
utils.print_dict(threshold.to_dict())
@utils.arg('-t', '--threshold-id',
@utils.arg('-i', '--threshold-id',
help='Threshold uuid',
required=True)
def do_hashmap_threshold_group(cc, args={}):

View File

@@ -1,42 +0,0 @@
Name: python-cloudkittyclient
Version: @VERSION@
Release: 1%{?dist}
Summary: Client library for CloudKitty
License: ASL 2.0
Source: %{name}-%{version}.tar.gz
BuildArch: noarch
BuildRequires: python-setuptools
BuildRequires: python-pbr
BuildRequires: python-keystoneclient
BuildRequires: python-stevedore
BuildRequires: python-babel
Requires: python-keystoneclient
Requires: python-stevedore
Requires: python-babel
%description
Client library for CloudKitty
%prep
%setup -q
%build
%{__python} setup.py build
%install
%{__python} setup.py install -O1 --skip-build --root %{buildroot}
#export PYTHONPATH="$( pwd ):$PYTHONPATH"
#sphinx-build -b html doc/source html
%files
%{_bindir}/*
%{python_sitelib}/*
#%doc html
%changelog
* Sun Apr 19 2015 Gauvain Pocentek <gauvain.pocentek@objectif-libre.com> @VERSION@-1
- Initial release

0
doc/source/conf.py Executable file → Normal file
View File

View File

@@ -3,9 +3,10 @@
# process, which may cause wedges in the gate later.
pbr>=1.6 # Apache-2.0
Babel>=1.3 # BSD
python-keystoneclient!=1.8.0,!=2.1.0,>=1.6.0 # Apache-2.0
stevedore>=1.5.0 # Apache-2.0
Babel>=2.3.4 # BSD
python-keystoneclient!=1.8.0,!=2.1.0,>=1.7.0 # Apache-2.0
stevedore>=1.10.0 # Apache-2.0
oslo.i18n>=2.1.0 # Apache-2.0
oslo.serialization>=1.10.0 # Apache-2.0
oslo.utils>=3.5.0 # Apache-2.0
oslo.utils>=3.11.0 # Apache-2.0
PrettyTable<0.8,>=0.7 # BSD

View File

@@ -5,7 +5,6 @@
hacking<0.10,>=0.9.2
coverage>=3.6 # Apache-2.0
discover # BSD
python-subunit>=0.0.18 # Apache-2.0/BSD
sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0