Use modules from oslo istead of openstack-common
Change-Id: Iaf6c3624e38db17e1f6e13bd5c1c2f236487544b
This commit is contained in:
parent
08e447ea8a
commit
47c755f31e
@ -18,13 +18,13 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
|
from oslo.serialization import jsonutils
|
||||||
|
from oslo.utils import encodeutils
|
||||||
import requests
|
import requests
|
||||||
import six
|
import six
|
||||||
from six.moves.urllib import parse
|
from six.moves.urllib import parse
|
||||||
|
|
||||||
from muranoclient.common import exceptions as exc
|
from muranoclient.common import exceptions as exc
|
||||||
from muranoclient.openstack.common import jsonutils
|
|
||||||
from muranoclient.openstack.common import strutils
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
USER_AGENT = 'python-muranoclient'
|
USER_AGENT = 'python-muranoclient'
|
||||||
@ -83,8 +83,8 @@ class HTTPClient(object):
|
|||||||
curl = ['curl -i -X %s' % method]
|
curl = ['curl -i -X %s' % method]
|
||||||
|
|
||||||
for (key, value) in kwargs['headers'].items():
|
for (key, value) in kwargs['headers'].items():
|
||||||
header = '-H \'%s: %s\'' % (strutils.safe_decode(key),
|
header = '-H \'%s: %s\'' % (encodeutils.safe_decode(key),
|
||||||
strutils.safe_decode(value))
|
encodeutils.safe_decode(value))
|
||||||
curl.append(header)
|
curl.append(header)
|
||||||
|
|
||||||
conn_params_fmt = [
|
conn_params_fmt = [
|
||||||
@ -116,7 +116,7 @@ class HTTPClient(object):
|
|||||||
content = resp.content
|
content = resp.content
|
||||||
if isinstance(content, six.binary_type):
|
if isinstance(content, six.binary_type):
|
||||||
try:
|
try:
|
||||||
content = strutils.safe_decode(resp.content)
|
content = encodeutils.safe_decode(resp.content)
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
@ -22,6 +22,9 @@ import textwrap
|
|||||||
import types
|
import types
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
from oslo.serialization import jsonutils
|
||||||
|
from oslo.utils import encodeutils
|
||||||
|
from oslo.utils import importutils
|
||||||
import prettytable
|
import prettytable
|
||||||
import six
|
import six
|
||||||
import yaml
|
import yaml
|
||||||
@ -29,9 +32,6 @@ import yaql
|
|||||||
import yaql.exceptions
|
import yaql.exceptions
|
||||||
|
|
||||||
from muranoclient.common import exceptions
|
from muranoclient.common import exceptions
|
||||||
from muranoclient.openstack.common import importutils
|
|
||||||
from muranoclient.openstack.common import jsonutils
|
|
||||||
from muranoclient.openstack.common import strutils
|
|
||||||
|
|
||||||
|
|
||||||
# Decorator for cli-args
|
# Decorator for cli-args
|
||||||
@ -69,7 +69,7 @@ def print_list(objs, fields, field_labels, formatters={}, sortby=0):
|
|||||||
data = getattr(o, field, None) or ''
|
data = getattr(o, field, None) or ''
|
||||||
row.append(data)
|
row.append(data)
|
||||||
pt.add_row(row)
|
pt.add_row(row)
|
||||||
print(strutils.safe_encode(pt.get_string()))
|
print(encodeutils.safe_encode(pt.get_string()))
|
||||||
|
|
||||||
|
|
||||||
def print_dict(d, formatters={}):
|
def print_dict(d, formatters={}):
|
||||||
@ -81,7 +81,7 @@ def print_dict(d, formatters={}):
|
|||||||
pt.add_row([field, formatters[field](d[field])])
|
pt.add_row([field, formatters[field](d[field])])
|
||||||
else:
|
else:
|
||||||
pt.add_row([field, d[field]])
|
pt.add_row([field, d[field]])
|
||||||
print(strutils.safe_encode(pt.get_string(sortby='Property')))
|
print(encodeutils.safe_encode(pt.get_string(sortby='Property')))
|
||||||
|
|
||||||
|
|
||||||
def find_resource(manager, name_or_id):
|
def find_resource(manager, name_or_id):
|
||||||
@ -135,7 +135,7 @@ def import_versioned_module(version, submodule=None):
|
|||||||
|
|
||||||
def exit(msg=''):
|
def exit(msg=''):
|
||||||
if msg:
|
if msg:
|
||||||
print(strutils.safe_encode(msg), file=sys.stderr)
|
print(encodeutils.safe_encode(msg), file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ def exception_to_str(exc):
|
|||||||
except UnicodeError:
|
except UnicodeError:
|
||||||
error = ("Caught '%(exception)s' exception." %
|
error = ("Caught '%(exception)s' exception." %
|
||||||
{"exception": exc.__class__.__name__})
|
{"exception": exc.__class__.__name__})
|
||||||
return strutils.safe_encode(error, errors='ignore')
|
return encodeutils.safe_encode(error, errors='ignore')
|
||||||
|
|
||||||
|
|
||||||
class YaqlExpression(object):
|
class YaqlExpression(object):
|
||||||
|
@ -26,13 +26,13 @@ Base utilities to build API operation managers and objects on top of.
|
|||||||
import abc
|
import abc
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
|
from oslo.utils import strutils
|
||||||
|
from oslo.utils import uuidutils
|
||||||
import six
|
import six
|
||||||
from six.moves.urllib import parse
|
from six.moves.urllib import parse
|
||||||
|
|
||||||
from muranoclient.openstack.common.apiclient import exceptions
|
from muranoclient.openstack.common.apiclient import exceptions
|
||||||
from muranoclient.openstack.common.gettextutils import _
|
from muranoclient.openstack.common.gettextutils import _
|
||||||
from muranoclient.openstack.common import strutils
|
|
||||||
from muranoclient.openstack.common import uuidutils
|
|
||||||
|
|
||||||
|
|
||||||
def getid(obj):
|
def getid(obj):
|
||||||
|
@ -35,9 +35,10 @@ except ImportError:
|
|||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
from oslo.utils import importutils
|
||||||
|
|
||||||
from muranoclient.openstack.common.apiclient import exceptions
|
from muranoclient.openstack.common.apiclient import exceptions
|
||||||
from muranoclient.openstack.common.gettextutils import _
|
from muranoclient.openstack.common.gettextutils import _
|
||||||
from muranoclient.openstack.common import importutils
|
|
||||||
|
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
@ -28,10 +28,11 @@ import prettytable
|
|||||||
import six
|
import six
|
||||||
from six import moves
|
from six import moves
|
||||||
|
|
||||||
|
from oslo.utils import encodeutils
|
||||||
|
from oslo.utils import strutils
|
||||||
|
from oslo.utils import uuidutils
|
||||||
from muranoclient.openstack.common.apiclient import exceptions
|
from muranoclient.openstack.common.apiclient import exceptions
|
||||||
from muranoclient.openstack.common.gettextutils import _
|
from muranoclient.openstack.common.gettextutils import _
|
||||||
from muranoclient.openstack.common import strutils
|
|
||||||
from muranoclient.openstack.common import uuidutils
|
|
||||||
|
|
||||||
|
|
||||||
def validate_args(fn, *args, **kwargs):
|
def validate_args(fn, *args, **kwargs):
|
||||||
@ -165,7 +166,7 @@ def print_list(objs, fields, formatters=None, sortby_index=0,
|
|||||||
row.append(data)
|
row.append(data)
|
||||||
pt.add_row(row)
|
pt.add_row(row)
|
||||||
|
|
||||||
print(strutils.safe_encode(pt.get_string(**kwargs)))
|
print(encodeutils.safe_encode(pt.get_string(**kwargs)))
|
||||||
|
|
||||||
|
|
||||||
def print_dict(dct, dict_property="Property", wrap=0):
|
def print_dict(dct, dict_property="Property", wrap=0):
|
||||||
@ -193,7 +194,7 @@ def print_dict(dct, dict_property="Property", wrap=0):
|
|||||||
col1 = ''
|
col1 = ''
|
||||||
else:
|
else:
|
||||||
pt.add_row([k, v])
|
pt.add_row([k, v])
|
||||||
print(strutils.safe_encode(pt.get_string()))
|
print(encodeutils.safe_encode(pt.get_string()))
|
||||||
|
|
||||||
|
|
||||||
def get_password(max_password_prompts=3):
|
def get_password(max_password_prompts=3):
|
||||||
@ -238,9 +239,9 @@ def find_resource(manager, name_or_id, **find_args):
|
|||||||
# now try to get entity as uuid
|
# now try to get entity as uuid
|
||||||
try:
|
try:
|
||||||
if six.PY2:
|
if six.PY2:
|
||||||
tmp_id = strutils.safe_encode(name_or_id)
|
tmp_id = encodeutils.safe_encode(name_or_id)
|
||||||
else:
|
else:
|
||||||
tmp_id = strutils.safe_decode(name_or_id)
|
tmp_id = encodeutils.safe_decode(name_or_id)
|
||||||
|
|
||||||
if uuidutils.is_uuid_like(tmp_id):
|
if uuidutils.is_uuid_like(tmp_id):
|
||||||
return manager.get(tmp_id)
|
return manager.get(tmp_id)
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
# Copyright 2011 OpenStack Foundation.
|
|
||||||
# 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 related utilities and helper functions.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
|
|
||||||
def import_class(import_str):
|
|
||||||
"""Returns a class from a string including module and class."""
|
|
||||||
mod_str, _sep, class_str = import_str.rpartition('.')
|
|
||||||
__import__(mod_str)
|
|
||||||
try:
|
|
||||||
return getattr(sys.modules[mod_str], class_str)
|
|
||||||
except AttributeError:
|
|
||||||
raise ImportError('Class %s cannot be found (%s)' %
|
|
||||||
(class_str,
|
|
||||||
traceback.format_exception(*sys.exc_info())))
|
|
||||||
|
|
||||||
|
|
||||||
def import_object(import_str, *args, **kwargs):
|
|
||||||
"""Import a class and return an instance of it."""
|
|
||||||
return import_class(import_str)(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def import_object_ns(name_space, import_str, *args, **kwargs):
|
|
||||||
"""Tries to import object from default namespace.
|
|
||||||
|
|
||||||
Imports a class and return an instance of it, first by trying
|
|
||||||
to find the class in a default namespace, then failing back to
|
|
||||||
a full path if not found in the default namespace.
|
|
||||||
"""
|
|
||||||
import_value = "%s.%s" % (name_space, import_str)
|
|
||||||
try:
|
|
||||||
return import_class(import_value)(*args, **kwargs)
|
|
||||||
except ImportError:
|
|
||||||
return import_class(import_str)(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def import_module(import_str):
|
|
||||||
"""Import a module."""
|
|
||||||
__import__(import_str)
|
|
||||||
return sys.modules[import_str]
|
|
||||||
|
|
||||||
|
|
||||||
def import_versioned_module(version, submodule=None):
|
|
||||||
module = 'muranoclient.v%s' % version
|
|
||||||
if submodule:
|
|
||||||
module = '.'.join((module, submodule))
|
|
||||||
return import_module(module)
|
|
||||||
|
|
||||||
|
|
||||||
def try_import(import_str, default=None):
|
|
||||||
"""Try to import a module and if it fails return default."""
|
|
||||||
try:
|
|
||||||
return import_module(import_str)
|
|
||||||
except ImportError:
|
|
||||||
return default
|
|
@ -1,186 +0,0 @@
|
|||||||
# Copyright 2010 United States Government as represented by the
|
|
||||||
# Administrator of the National Aeronautics and Space Administration.
|
|
||||||
# Copyright 2011 Justin Santa Barbara
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
'''
|
|
||||||
JSON related utilities.
|
|
||||||
|
|
||||||
This module provides a few things:
|
|
||||||
|
|
||||||
1) A handy function for getting an object down to something that can be
|
|
||||||
JSON serialized. See to_primitive().
|
|
||||||
|
|
||||||
2) Wrappers around loads() and dumps(). The dumps() wrapper will
|
|
||||||
automatically use to_primitive() for you if needed.
|
|
||||||
|
|
||||||
3) This sets up anyjson to use the loads() and dumps() wrappers if anyjson
|
|
||||||
is available.
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
import codecs
|
|
||||||
import datetime
|
|
||||||
import functools
|
|
||||||
import inspect
|
|
||||||
import itertools
|
|
||||||
import sys
|
|
||||||
|
|
||||||
if sys.version_info < (2, 7):
|
|
||||||
# On Python <= 2.6, json module is not C boosted, so try to use
|
|
||||||
# simplejson module if available
|
|
||||||
try:
|
|
||||||
import simplejson as json
|
|
||||||
except ImportError:
|
|
||||||
import json
|
|
||||||
else:
|
|
||||||
import json
|
|
||||||
|
|
||||||
import six
|
|
||||||
import six.moves.xmlrpc_client as xmlrpclib
|
|
||||||
|
|
||||||
from muranoclient.openstack.common import gettextutils
|
|
||||||
from muranoclient.openstack.common import importutils
|
|
||||||
from muranoclient.openstack.common import strutils
|
|
||||||
from muranoclient.openstack.common import timeutils
|
|
||||||
|
|
||||||
netaddr = importutils.try_import("netaddr")
|
|
||||||
|
|
||||||
_nasty_type_tests = [inspect.ismodule, inspect.isclass, inspect.ismethod,
|
|
||||||
inspect.isfunction, inspect.isgeneratorfunction,
|
|
||||||
inspect.isgenerator, inspect.istraceback, inspect.isframe,
|
|
||||||
inspect.iscode, inspect.isbuiltin, inspect.isroutine,
|
|
||||||
inspect.isabstract]
|
|
||||||
|
|
||||||
_simple_types = (six.string_types + six.integer_types
|
|
||||||
+ (type(None), bool, float))
|
|
||||||
|
|
||||||
|
|
||||||
def to_primitive(value, convert_instances=False, convert_datetime=True,
|
|
||||||
level=0, max_depth=3):
|
|
||||||
"""Convert a complex object into primitives.
|
|
||||||
|
|
||||||
Handy for JSON serialization. We can optionally handle instances,
|
|
||||||
but since this is a recursive function, we could have cyclical
|
|
||||||
data structures.
|
|
||||||
|
|
||||||
To handle cyclical data structures we could track the actual objects
|
|
||||||
visited in a set, but not all objects are hashable. Instead we just
|
|
||||||
track the depth of the object inspections and don't go too deep.
|
|
||||||
|
|
||||||
Therefore, convert_instances=True is lossy ... be aware.
|
|
||||||
|
|
||||||
"""
|
|
||||||
# handle obvious types first - order of basic types determined by running
|
|
||||||
# full tests on nova project, resulting in the following counts:
|
|
||||||
# 572754 <type 'NoneType'>
|
|
||||||
# 460353 <type 'int'>
|
|
||||||
# 379632 <type 'unicode'>
|
|
||||||
# 274610 <type 'str'>
|
|
||||||
# 199918 <type 'dict'>
|
|
||||||
# 114200 <type 'datetime.datetime'>
|
|
||||||
# 51817 <type 'bool'>
|
|
||||||
# 26164 <type 'list'>
|
|
||||||
# 6491 <type 'float'>
|
|
||||||
# 283 <type 'tuple'>
|
|
||||||
# 19 <type 'long'>
|
|
||||||
if isinstance(value, _simple_types):
|
|
||||||
return value
|
|
||||||
|
|
||||||
if isinstance(value, datetime.datetime):
|
|
||||||
if convert_datetime:
|
|
||||||
return timeutils.strtime(value)
|
|
||||||
else:
|
|
||||||
return value
|
|
||||||
|
|
||||||
# value of itertools.count doesn't get caught by nasty_type_tests
|
|
||||||
# and results in infinite loop when list(value) is called.
|
|
||||||
if type(value) == itertools.count:
|
|
||||||
return six.text_type(value)
|
|
||||||
|
|
||||||
# FIXME(vish): Workaround for LP bug 852095. Without this workaround,
|
|
||||||
# tests that raise an exception in a mocked method that
|
|
||||||
# has a @wrap_exception with a notifier will fail. If
|
|
||||||
# we up the dependency to 0.5.4 (when it is released) we
|
|
||||||
# can remove this workaround.
|
|
||||||
if getattr(value, '__module__', None) == 'mox':
|
|
||||||
return 'mock'
|
|
||||||
|
|
||||||
if level > max_depth:
|
|
||||||
return '?'
|
|
||||||
|
|
||||||
# The try block may not be necessary after the class check above,
|
|
||||||
# but just in case ...
|
|
||||||
try:
|
|
||||||
recursive = functools.partial(to_primitive,
|
|
||||||
convert_instances=convert_instances,
|
|
||||||
convert_datetime=convert_datetime,
|
|
||||||
level=level,
|
|
||||||
max_depth=max_depth)
|
|
||||||
if isinstance(value, dict):
|
|
||||||
return dict((k, recursive(v)) for k, v in six.iteritems(value))
|
|
||||||
elif isinstance(value, (list, tuple)):
|
|
||||||
return [recursive(lv) for lv in value]
|
|
||||||
|
|
||||||
# It's not clear why xmlrpclib created their own DateTime type, but
|
|
||||||
# for our purposes, make it a datetime type which is explicitly
|
|
||||||
# handled
|
|
||||||
if isinstance(value, xmlrpclib.DateTime):
|
|
||||||
value = datetime.datetime(*tuple(value.timetuple())[:6])
|
|
||||||
|
|
||||||
if convert_datetime and isinstance(value, datetime.datetime):
|
|
||||||
return timeutils.strtime(value)
|
|
||||||
elif isinstance(value, gettextutils.Message):
|
|
||||||
return value.data
|
|
||||||
elif hasattr(value, 'iteritems'):
|
|
||||||
return recursive(dict(value.iteritems()), level=level + 1)
|
|
||||||
elif hasattr(value, '__iter__'):
|
|
||||||
return recursive(list(value))
|
|
||||||
elif convert_instances and hasattr(value, '__dict__'):
|
|
||||||
# Likely an instance of something. Watch for cycles.
|
|
||||||
# Ignore class member vars.
|
|
||||||
return recursive(value.__dict__, level=level + 1)
|
|
||||||
elif netaddr and isinstance(value, netaddr.IPAddress):
|
|
||||||
return six.text_type(value)
|
|
||||||
else:
|
|
||||||
if any(test(value) for test in _nasty_type_tests):
|
|
||||||
return six.text_type(value)
|
|
||||||
return value
|
|
||||||
except TypeError:
|
|
||||||
# Class objects are tricky since they may define something like
|
|
||||||
# __iter__ defined but it isn't callable as list().
|
|
||||||
return six.text_type(value)
|
|
||||||
|
|
||||||
|
|
||||||
def dumps(value, default=to_primitive, **kwargs):
|
|
||||||
return json.dumps(value, default=default, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def loads(s, encoding='utf-8', **kwargs):
|
|
||||||
return json.loads(strutils.safe_decode(s, encoding), **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def load(fp, encoding='utf-8', **kwargs):
|
|
||||||
return json.load(codecs.getreader(encoding)(fp), **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
import anyjson
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
anyjson._modules.append((__name__, 'dumps', TypeError,
|
|
||||||
'loads', ValueError, 'load'))
|
|
||||||
anyjson.force_implementation(__name__)
|
|
@ -1,239 +0,0 @@
|
|||||||
# Copyright 2011 OpenStack Foundation.
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
"""
|
|
||||||
System-level utilities and helper functions.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import math
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
import unicodedata
|
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from muranoclient.openstack.common.gettextutils import _
|
|
||||||
|
|
||||||
|
|
||||||
UNIT_PREFIX_EXPONENT = {
|
|
||||||
'k': 1,
|
|
||||||
'K': 1,
|
|
||||||
'Ki': 1,
|
|
||||||
'M': 2,
|
|
||||||
'Mi': 2,
|
|
||||||
'G': 3,
|
|
||||||
'Gi': 3,
|
|
||||||
'T': 4,
|
|
||||||
'Ti': 4,
|
|
||||||
}
|
|
||||||
UNIT_SYSTEM_INFO = {
|
|
||||||
'IEC': (1024, re.compile(r'(^[-+]?\d*\.?\d+)([KMGT]i?)?(b|bit|B)$')),
|
|
||||||
'SI': (1000, re.compile(r'(^[-+]?\d*\.?\d+)([kMGT])?(b|bit|B)$')),
|
|
||||||
}
|
|
||||||
|
|
||||||
TRUE_STRINGS = ('1', 't', 'true', 'on', 'y', 'yes')
|
|
||||||
FALSE_STRINGS = ('0', 'f', 'false', 'off', 'n', 'no')
|
|
||||||
|
|
||||||
SLUGIFY_STRIP_RE = re.compile(r"[^\w\s-]")
|
|
||||||
SLUGIFY_HYPHENATE_RE = re.compile(r"[-\s]+")
|
|
||||||
|
|
||||||
|
|
||||||
def int_from_bool_as_string(subject):
|
|
||||||
"""Interpret a string as a boolean and return either 1 or 0.
|
|
||||||
|
|
||||||
Any string value in:
|
|
||||||
|
|
||||||
('True', 'true', 'On', 'on', '1')
|
|
||||||
|
|
||||||
is interpreted as a boolean True.
|
|
||||||
|
|
||||||
Useful for JSON-decoded stuff and config file parsing
|
|
||||||
"""
|
|
||||||
return bool_from_string(subject) and 1 or 0
|
|
||||||
|
|
||||||
|
|
||||||
def bool_from_string(subject, strict=False, default=False):
|
|
||||||
"""Interpret a string as a boolean.
|
|
||||||
|
|
||||||
A case-insensitive match is performed such that strings matching 't',
|
|
||||||
'true', 'on', 'y', 'yes', or '1' are considered True and, when
|
|
||||||
`strict=False`, anything else returns the value specified by 'default'.
|
|
||||||
|
|
||||||
Useful for JSON-decoded stuff and config file parsing.
|
|
||||||
|
|
||||||
If `strict=True`, unrecognized values, including None, will raise a
|
|
||||||
ValueError which is useful when parsing values passed in from an API call.
|
|
||||||
Strings yielding False are 'f', 'false', 'off', 'n', 'no', or '0'.
|
|
||||||
"""
|
|
||||||
if not isinstance(subject, six.string_types):
|
|
||||||
subject = six.text_type(subject)
|
|
||||||
|
|
||||||
lowered = subject.strip().lower()
|
|
||||||
|
|
||||||
if lowered in TRUE_STRINGS:
|
|
||||||
return True
|
|
||||||
elif lowered in FALSE_STRINGS:
|
|
||||||
return False
|
|
||||||
elif strict:
|
|
||||||
acceptable = ', '.join(
|
|
||||||
"'%s'" % s for s in sorted(TRUE_STRINGS + FALSE_STRINGS))
|
|
||||||
msg = _("Unrecognized value '%(val)s', acceptable values are:"
|
|
||||||
" %(acceptable)s") % {'val': subject,
|
|
||||||
'acceptable': acceptable}
|
|
||||||
raise ValueError(msg)
|
|
||||||
else:
|
|
||||||
return default
|
|
||||||
|
|
||||||
|
|
||||||
def safe_decode(text, incoming=None, errors='strict'):
|
|
||||||
"""Decodes incoming text/bytes string using `incoming` if they're not
|
|
||||||
already unicode.
|
|
||||||
|
|
||||||
:param incoming: Text's current encoding
|
|
||||||
:param errors: Errors handling policy. See here for valid
|
|
||||||
values http://docs.python.org/2/library/codecs.html
|
|
||||||
:returns: text or a unicode `incoming` encoded
|
|
||||||
representation of it.
|
|
||||||
:raises TypeError: If text is not an instance of str
|
|
||||||
"""
|
|
||||||
if not isinstance(text, (six.string_types, six.binary_type)):
|
|
||||||
raise TypeError("%s can't be decoded" % type(text))
|
|
||||||
|
|
||||||
if isinstance(text, six.text_type):
|
|
||||||
return text
|
|
||||||
|
|
||||||
if not incoming:
|
|
||||||
incoming = (sys.stdin.encoding or
|
|
||||||
sys.getdefaultencoding())
|
|
||||||
|
|
||||||
try:
|
|
||||||
return text.decode(incoming, errors)
|
|
||||||
except UnicodeDecodeError:
|
|
||||||
# Note(flaper87) If we get here, it means that
|
|
||||||
# sys.stdin.encoding / sys.getdefaultencoding
|
|
||||||
# didn't return a suitable encoding to decode
|
|
||||||
# text. This happens mostly when global LANG
|
|
||||||
# var is not set correctly and there's no
|
|
||||||
# default encoding. In this case, most likely
|
|
||||||
# python will use ASCII or ANSI encoders as
|
|
||||||
# default encodings but they won't be capable
|
|
||||||
# of decoding non-ASCII characters.
|
|
||||||
#
|
|
||||||
# Also, UTF-8 is being used since it's an ASCII
|
|
||||||
# extension.
|
|
||||||
return text.decode('utf-8', errors)
|
|
||||||
|
|
||||||
|
|
||||||
def safe_encode(text, incoming=None,
|
|
||||||
encoding='utf-8', errors='strict'):
|
|
||||||
"""Encodes incoming text/bytes string using `encoding`.
|
|
||||||
|
|
||||||
If incoming is not specified, text is expected to be encoded with
|
|
||||||
current python's default encoding. (`sys.getdefaultencoding`)
|
|
||||||
|
|
||||||
:param incoming: Text's current encoding
|
|
||||||
:param encoding: Expected encoding for text (Default UTF-8)
|
|
||||||
:param errors: Errors handling policy. See here for valid
|
|
||||||
values http://docs.python.org/2/library/codecs.html
|
|
||||||
:returns: text or a bytestring `encoding` encoded
|
|
||||||
representation of it.
|
|
||||||
:raises TypeError: If text is not an instance of str
|
|
||||||
"""
|
|
||||||
if not isinstance(text, (six.string_types, six.binary_type)):
|
|
||||||
raise TypeError("%s can't be encoded" % type(text))
|
|
||||||
|
|
||||||
if not incoming:
|
|
||||||
incoming = (sys.stdin.encoding or
|
|
||||||
sys.getdefaultencoding())
|
|
||||||
|
|
||||||
if isinstance(text, six.text_type):
|
|
||||||
return text.encode(encoding, errors)
|
|
||||||
elif text and encoding != incoming:
|
|
||||||
# Decode text before encoding it with `encoding`
|
|
||||||
text = safe_decode(text, incoming, errors)
|
|
||||||
return text.encode(encoding, errors)
|
|
||||||
else:
|
|
||||||
return text
|
|
||||||
|
|
||||||
|
|
||||||
def string_to_bytes(text, unit_system='IEC', return_int=False):
|
|
||||||
"""Converts a string into an float representation of bytes.
|
|
||||||
|
|
||||||
The units supported for IEC ::
|
|
||||||
|
|
||||||
Kb(it), Kib(it), Mb(it), Mib(it), Gb(it), Gib(it), Tb(it), Tib(it)
|
|
||||||
KB, KiB, MB, MiB, GB, GiB, TB, TiB
|
|
||||||
|
|
||||||
The units supported for SI ::
|
|
||||||
|
|
||||||
kb(it), Mb(it), Gb(it), Tb(it)
|
|
||||||
kB, MB, GB, TB
|
|
||||||
|
|
||||||
Note that the SI unit system does not support capital letter 'K'
|
|
||||||
|
|
||||||
:param text: String input for bytes size conversion.
|
|
||||||
:param unit_system: Unit system for byte size conversion.
|
|
||||||
:param return_int: If True, returns integer representation of text
|
|
||||||
in bytes. (default: decimal)
|
|
||||||
:returns: Numerical representation of text in bytes.
|
|
||||||
:raises ValueError: If text has an invalid value.
|
|
||||||
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
base, reg_ex = UNIT_SYSTEM_INFO[unit_system]
|
|
||||||
except KeyError:
|
|
||||||
msg = _('Invalid unit system: "%s"') % unit_system
|
|
||||||
raise ValueError(msg)
|
|
||||||
match = reg_ex.match(text)
|
|
||||||
if match:
|
|
||||||
magnitude = float(match.group(1))
|
|
||||||
unit_prefix = match.group(2)
|
|
||||||
if match.group(3) in ['b', 'bit']:
|
|
||||||
magnitude /= 8
|
|
||||||
else:
|
|
||||||
msg = _('Invalid string format: %s') % text
|
|
||||||
raise ValueError(msg)
|
|
||||||
if not unit_prefix:
|
|
||||||
res = magnitude
|
|
||||||
else:
|
|
||||||
res = magnitude * pow(base, UNIT_PREFIX_EXPONENT[unit_prefix])
|
|
||||||
if return_int:
|
|
||||||
return int(math.ceil(res))
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
|
||||||
def to_slug(value, incoming=None, errors="strict"):
|
|
||||||
"""Normalize string.
|
|
||||||
|
|
||||||
Convert to lowercase, remove non-word characters, and convert spaces
|
|
||||||
to hyphens.
|
|
||||||
|
|
||||||
Inspired by Django's `slugify` filter.
|
|
||||||
|
|
||||||
:param value: Text to slugify
|
|
||||||
:param incoming: Text's current encoding
|
|
||||||
:param errors: Errors handling policy. See here for valid
|
|
||||||
values http://docs.python.org/2/library/codecs.html
|
|
||||||
:returns: slugified unicode representation of `value`
|
|
||||||
:raises TypeError: If text is not an instance of str
|
|
||||||
"""
|
|
||||||
value = safe_decode(value, incoming, errors)
|
|
||||||
# NOTE(aababilov): no need to use safe_(encode|decode) here:
|
|
||||||
# encodings are always "ascii", error handling is always "ignore"
|
|
||||||
# and types are always known (first: unicode; second: str)
|
|
||||||
value = unicodedata.normalize("NFKD", value).encode(
|
|
||||||
"ascii", "ignore").decode("ascii")
|
|
||||||
value = SLUGIFY_STRIP_RE.sub("", value).strip().lower()
|
|
||||||
return SLUGIFY_HYPHENATE_RE.sub("-", value)
|
|
@ -1,37 +0,0 @@
|
|||||||
# Copyright (c) 2012 Intel Corporation.
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
"""
|
|
||||||
UUID related utilities and helper functions.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
|
|
||||||
def generate_uuid():
|
|
||||||
return str(uuid.uuid4())
|
|
||||||
|
|
||||||
|
|
||||||
def is_uuid_like(val):
|
|
||||||
"""Returns validation of a value as a UUID.
|
|
||||||
|
|
||||||
For our purposes, a UUID is a canonical form string:
|
|
||||||
aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
|
|
||||||
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return str(uuid.UUID(val)) == val
|
|
||||||
except (TypeError, ValueError, AttributeError):
|
|
||||||
return False
|
|
@ -23,12 +23,12 @@ import logging
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from keystoneclient.v2_0 import client as ksclient
|
from keystoneclient.v2_0 import client as ksclient
|
||||||
|
from oslo.utils import encodeutils
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from muranoclient import client as apiclient
|
from muranoclient import client as apiclient
|
||||||
from muranoclient.common import utils
|
from muranoclient.common import utils
|
||||||
from muranoclient.openstack.common.apiclient import exceptions as exc
|
from muranoclient.openstack.common.apiclient import exceptions as exc
|
||||||
from muranoclient.openstack.common import strutils
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -394,7 +394,7 @@ def main(args=None):
|
|||||||
if '--debug' in args or '-d' in args:
|
if '--debug' in args or '-d' in args:
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
print(strutils.safe_encode(six.text_type(e)), file=sys.stderr)
|
print(encodeutils.safe_encode(six.text_type(e)), file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from muranoclient.openstack.common import jsonutils
|
from oslo.serialization import jsonutils
|
||||||
|
|
||||||
|
|
||||||
class FakeHTTPResponse():
|
class FakeHTTPResponse():
|
||||||
|
@ -2,9 +2,6 @@
|
|||||||
|
|
||||||
# The list of modules to copy from openstack-common
|
# The list of modules to copy from openstack-common
|
||||||
module=apiclient.exceptions
|
module=apiclient.exceptions
|
||||||
module=importutils
|
|
||||||
module=strutils
|
|
||||||
module=jsonutils
|
|
||||||
module=cliutils
|
module=cliutils
|
||||||
module=apiclient
|
module=apiclient
|
||||||
|
|
||||||
|
@ -13,5 +13,8 @@ pyOpenSSL>=0.11
|
|||||||
requests>=1.2.1,!=2.4.0
|
requests>=1.2.1,!=2.4.0
|
||||||
PyYAML>=3.1.0
|
PyYAML>=3.1.0
|
||||||
|
|
||||||
|
oslo.serialization>=1.0.0 # Apache-2.0
|
||||||
|
oslo.utils>=1.1.0 # Apache-2.0
|
||||||
|
|
||||||
# not listed in global requirements
|
# not listed in global requirements
|
||||||
yaql>=0.2.2,<0.3
|
yaql>=0.2.2,<0.3
|
||||||
|
Loading…
Reference in New Issue
Block a user