Add common utils
Taken from ceilometerclient. Will be useful for printing output and importing versioned modules.
This commit is contained in:
133
tuskarclient/common/utils.py
Normal file
133
tuskarclient/common/utils.py
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
# Copyright 2012 OpenStack LLC.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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 os
|
||||||
|
import sys
|
||||||
|
import textwrap
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
import prettytable
|
||||||
|
|
||||||
|
from tuskarclient import exc
|
||||||
|
from tuskarclient.openstack.common import importutils
|
||||||
|
|
||||||
|
|
||||||
|
# Decorator for cli-args
|
||||||
|
def arg(*args, **kwargs):
|
||||||
|
def _decorator(func):
|
||||||
|
# Because of the sematics of decorator composition if we just append
|
||||||
|
# to the options list positional options will appear to be backwards.
|
||||||
|
func.__dict__.setdefault('arguments', []).insert(0, (args, kwargs))
|
||||||
|
return func
|
||||||
|
return _decorator
|
||||||
|
|
||||||
|
|
||||||
|
def pretty_choice_list(l):
|
||||||
|
return ', '.join("'%s'" % i for i in l)
|
||||||
|
|
||||||
|
|
||||||
|
def print_list(objs, fields, field_labels, formatters={}, sortby=0):
|
||||||
|
pt = prettytable.PrettyTable([f for f in field_labels],
|
||||||
|
caching=False, print_empty=False)
|
||||||
|
pt.align = 'l'
|
||||||
|
|
||||||
|
for o in objs:
|
||||||
|
row = []
|
||||||
|
for field in fields:
|
||||||
|
if field in formatters:
|
||||||
|
row.append(formatters[field](o))
|
||||||
|
else:
|
||||||
|
data = getattr(o, field, '')
|
||||||
|
row.append(data)
|
||||||
|
pt.add_row(row)
|
||||||
|
print pt.get_string(sortby=field_labels[sortby])
|
||||||
|
|
||||||
|
|
||||||
|
def print_dict(d, dict_property="Property", wrap=0):
|
||||||
|
pt = prettytable.PrettyTable([dict_property, 'Value'],
|
||||||
|
caching=False, print_empty=False)
|
||||||
|
pt.align = 'l'
|
||||||
|
for k, v in d.iteritems():
|
||||||
|
# convert dict to str to check length
|
||||||
|
if isinstance(v, dict):
|
||||||
|
v = str(v)
|
||||||
|
if wrap > 0:
|
||||||
|
v = textwrap.fill(str(v), wrap)
|
||||||
|
# if value has a newline, add in multiple rows
|
||||||
|
# e.g. fault with stacktrace
|
||||||
|
if v and isinstance(v, basestring) and r'\n' in v:
|
||||||
|
lines = v.strip().split(r'\n')
|
||||||
|
col1 = k
|
||||||
|
for line in lines:
|
||||||
|
pt.add_row([col1, line])
|
||||||
|
col1 = ''
|
||||||
|
else:
|
||||||
|
pt.add_row([k, v])
|
||||||
|
print pt.get_string()
|
||||||
|
|
||||||
|
|
||||||
|
def find_resource(manager, name_or_id):
|
||||||
|
"""Helper for the _find_* methods."""
|
||||||
|
# first try to get entity as integer id
|
||||||
|
try:
|
||||||
|
if isinstance(name_or_id, int) or name_or_id.isdigit():
|
||||||
|
return manager.get(int(name_or_id))
|
||||||
|
except exc.NotFound:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# now try to get entity as uuid
|
||||||
|
try:
|
||||||
|
uuid.UUID(str(name_or_id))
|
||||||
|
return manager.get(name_or_id)
|
||||||
|
except (ValueError, exc.NotFound):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# finally try to find entity by name
|
||||||
|
try:
|
||||||
|
return manager.find(name=name_or_id)
|
||||||
|
except exc.NotFound:
|
||||||
|
msg = "No %s with a name or ID of '%s' exists." % \
|
||||||
|
(manager.resource_class.__name__.lower(), name_or_id)
|
||||||
|
raise exc.CommandError(msg)
|
||||||
|
|
||||||
|
|
||||||
|
def string_to_bool(arg):
|
||||||
|
return arg.strip().lower() in ('t', 'true', 'yes', '1')
|
||||||
|
|
||||||
|
|
||||||
|
def env(*vars, **kwargs):
|
||||||
|
"""Search for the first defined of possibly many env vars
|
||||||
|
|
||||||
|
Returns the first environment variable defined in vars, or
|
||||||
|
returns the default defined in kwargs.
|
||||||
|
"""
|
||||||
|
for v in vars:
|
||||||
|
value = os.environ.get(v, None)
|
||||||
|
if value:
|
||||||
|
return value
|
||||||
|
return kwargs.get('default', '')
|
||||||
|
|
||||||
|
|
||||||
|
def import_versioned_module(version, submodule=None):
|
||||||
|
module = 'tuskarclient.v%s' % version
|
||||||
|
if submodule:
|
||||||
|
module = '.'.join((module, submodule))
|
||||||
|
return importutils.import_module(module)
|
||||||
|
|
||||||
|
|
||||||
|
def exit(msg=''):
|
||||||
|
if msg:
|
||||||
|
print >> sys.stderr, msg
|
||||||
|
sys.exit(1)
|
||||||
47
tuskarclient/tests/test_utils.py
Normal file
47
tuskarclient/tests/test_utils.py
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# Copyright 2013 OpenStack LLC.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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 cStringIO
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from tuskarclient.common import utils
|
||||||
|
from tuskarclient.tests import utils as test_utils
|
||||||
|
|
||||||
|
|
||||||
|
class UtilsTest(test_utils.TestCase):
|
||||||
|
|
||||||
|
def test_prettytable(self):
|
||||||
|
class Struct:
|
||||||
|
def __init__(self, **entries):
|
||||||
|
self.__dict__.update(entries)
|
||||||
|
|
||||||
|
# test that the prettytable output is wellformatted (left-aligned)
|
||||||
|
saved_stdout = sys.stdout
|
||||||
|
try:
|
||||||
|
sys.stdout = output_dict = cStringIO.StringIO()
|
||||||
|
utils.print_dict({'K': 'k', 'Key': 'Value'})
|
||||||
|
|
||||||
|
finally:
|
||||||
|
sys.stdout = saved_stdout
|
||||||
|
|
||||||
|
self.assertEqual(output_dict.getvalue(), '''\
|
||||||
|
+----------+-------+
|
||||||
|
| Property | Value |
|
||||||
|
+----------+-------+
|
||||||
|
| K | k |
|
||||||
|
| Key | Value |
|
||||||
|
+----------+-------+
|
||||||
|
''')
|
||||||
Reference in New Issue
Block a user