Merge "I18n"

This commit is contained in:
Jenkins
2014-11-07 11:55:14 +00:00
committed by Gerrit Code Review
11 changed files with 114 additions and 44 deletions

View File

@@ -19,6 +19,7 @@ import datetime
from oslo.utils import timeutils from oslo.utils import timeutils
from keystoneclient.i18n import _
from keystoneclient import service_catalog from keystoneclient import service_catalog
@@ -63,7 +64,7 @@ class AccessInfo(dict):
else: else:
auth_ref = AccessInfoV2(**kwargs) auth_ref = AccessInfoV2(**kwargs)
else: else:
raise NotImplementedError('Unrecognized auth response') raise NotImplementedError(_('Unrecognized auth response'))
else: else:
auth_ref = AccessInfoV2(**kwargs) auth_ref = AccessInfoV2(**kwargs)

View File

@@ -17,6 +17,8 @@ import six
import stevedore import stevedore
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _
# NOTE(jamielennox): The AUTH_INTERFACE is a special value that can be # NOTE(jamielennox): The AUTH_INTERFACE is a special value that can be
# requested from get_endpoint. If a plugin receives this as the value of # requested from get_endpoint. If a plugin receives this as the value of
@@ -40,7 +42,7 @@ def get_plugin_class(name):
name=name, name=name,
invoke_on_load=False) invoke_on_load=False)
except RuntimeError: except RuntimeError:
msg = 'The plugin %s could not be found' % name msg = _('The plugin %s could not be found') % name
raise exceptions.NoMatchingPlugin(msg) raise exceptions.NoMatchingPlugin(msg)
return mgr.driver return mgr.driver

View File

@@ -19,6 +19,7 @@ import six
from keystoneclient import _discover from keystoneclient import _discover
from keystoneclient.auth import base from keystoneclient.auth import base
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _LW
from keystoneclient import utils from keystoneclient import utils
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@@ -181,9 +182,9 @@ class BaseIdentityPlugin(base.BaseAuthPlugin):
return self.auth_url return self.auth_url
if not service_type: if not service_type:
LOG.warn('Plugin cannot return an endpoint without knowing the ' LOG.warn(_LW('Plugin cannot return an endpoint without knowing '
'service type that is required. Add service_type to ' 'the service type that is required. Add service_type '
'endpoint filtering data.') 'to endpoint filtering data.'))
return None return None
if not interface: if not interface:
@@ -216,8 +217,9 @@ class BaseIdentityPlugin(base.BaseAuthPlugin):
# NOTE(jamielennox): Again if we can't contact the server we fall # NOTE(jamielennox): Again if we can't contact the server we fall
# back to just returning the URL from the catalog. This may not be # back to just returning the URL from the catalog. This may not be
# the best default but we need it for now. # the best default but we need it for now.
LOG.warn('Failed to contact the endpoint at %s for discovery. ' LOG.warn(_LW('Failed to contact the endpoint at %s for discovery. '
'Fallback to using that endpoint as the base url.', url) 'Fallback to using that endpoint as the base url.'),
url)
else: else:
url = disc.url_for(version) url = disc.url_for(version)

View File

@@ -20,6 +20,8 @@ import six.moves.urllib.parse as urlparse
from keystoneclient import _discover from keystoneclient import _discover
from keystoneclient.auth.identity import base from keystoneclient.auth.identity import base
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _, _LW
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@@ -127,9 +129,9 @@ class BaseGenericPlugin(base.BaseIdentityPlugin):
except (exceptions.DiscoveryFailure, except (exceptions.DiscoveryFailure,
exceptions.HTTPError, exceptions.HTTPError,
exceptions.ConnectionError): exceptions.ConnectionError):
LOG.warn('Discovering versions from the identity service failed ' LOG.warn(_LW('Discovering versions from the identity service '
'when creating the password plugin. Attempting to ' 'failed when creating the password plugin. '
'determine version from URL.') 'Attempting to determine version from URL.'))
url_parts = urlparse.urlparse(self.auth_url) url_parts = urlparse.urlparse(self.auth_url)
path = url_parts.path.lower() path = url_parts.path.lower()
@@ -163,7 +165,7 @@ class BaseGenericPlugin(base.BaseIdentityPlugin):
return plugin return plugin
# so there were no URLs that i could use for auth of any version. # so there were no URLs that i could use for auth of any version.
msg = 'Could not determine a suitable URL for the plugin' msg = _('Could not determine a suitable URL for the plugin')
raise exceptions.DiscoveryFailure(msg) raise exceptions.DiscoveryFailure(msg)
def get_auth_ref(self, session, **kwargs): def get_auth_ref(self, session, **kwargs):

View File

@@ -19,6 +19,7 @@ import six
from keystoneclient import access from keystoneclient import access
from keystoneclient.auth.identity import base from keystoneclient.auth.identity import base
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _
from keystoneclient import utils from keystoneclient import utils
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@@ -84,18 +85,17 @@ class Auth(base.BaseIdentityPlugin):
ident[name] = auth_data ident[name] = auth_data
if not ident: if not ident:
raise exceptions.AuthorizationFailure('Authentication method ' raise exceptions.AuthorizationFailure(
'required (e.g. password)') _('Authentication method required (e.g. password)'))
mutual_exclusion = [bool(self.domain_id or self.domain_name), mutual_exclusion = [bool(self.domain_id or self.domain_name),
bool(self.project_id or self.project_name), bool(self.project_id or self.project_name),
bool(self.trust_id)] bool(self.trust_id)]
if sum(mutual_exclusion) > 1: if sum(mutual_exclusion) > 1:
raise exceptions.AuthorizationFailure('Authentication cannot be ' raise exceptions.AuthorizationFailure(
'scoped to multiple ' _('Authentication cannot be scoped to multiple targets. Pick '
'targets. Pick one of: ' 'one of: project, domain or trust'))
'project, domain or trust')
if self.domain_id: if self.domain_id:
body['auth']['scope'] = {'domain': {'id': self.domain_id}} body['auth']['scope'] = {'domain': {'id': self.domain_id}}
@@ -165,7 +165,7 @@ class AuthMethod(object):
setattr(self, param, kwargs.pop(param, None)) setattr(self, param, kwargs.pop(param, None))
if kwargs: if kwargs:
msg = "Unexpected Attributes: %s" % ", ".join(kwargs.keys()) msg = _("Unexpected Attributes: %s") % ", ".join(kwargs.keys())
raise AttributeError(msg) raise AttributeError(msg)
@classmethod @classmethod

View File

@@ -16,6 +16,7 @@
Exception definitions. Exception definitions.
""" """
from keystoneclient.i18n import _
from keystoneclient.openstack.common.apiclient.exceptions import * # noqa from keystoneclient.openstack.common.apiclient.exceptions import * # noqa
# NOTE(akurilin): This alias should be left here to support backwards # NOTE(akurilin): This alias should be left here to support backwards
@@ -31,7 +32,7 @@ class CertificateConfigError(Exception):
"""Error reading the certificate.""" """Error reading the certificate."""
def __init__(self, output): def __init__(self, output):
self.output = output self.output = output
msg = 'Unable to load certificate.' msg = _('Unable to load certificate.')
super(CertificateConfigError, self).__init__(msg) super(CertificateConfigError, self).__init__(msg)
@@ -39,7 +40,7 @@ class CMSError(Exception):
"""Error reading the certificate.""" """Error reading the certificate."""
def __init__(self, output): def __init__(self, output):
self.output = output self.output = output
msg = 'Unable to sign or verify data.' msg = _('Unable to sign or verify data.')
super(CMSError, self).__init__(msg) super(CMSError, self).__init__(msg)

37
keystoneclient/i18n.py Normal file
View File

@@ -0,0 +1,37 @@
# Copyright 2014 IBM Corp.
#
# 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.
"""oslo.i18n integration module.
See http://docs.openstack.org/developer/oslo.i18n/usage.html .
"""
from oslo import i18n
_translators = i18n.TranslatorFactory(domain='keystoneclient')
# The primary translation function using the well-known name "_"
_ = _translators.primary
# Translators for log levels.
#
# The abbreviated names are meant to reflect the usual use of a short
# name like '_'. The "L" is for "log" and the other letter comes from
# the level.
_LI = _translators.log_info
_LW = _translators.log_warning
_LE = _translators.log_error
_LC = _translators.log_critical

View File

@@ -21,6 +21,7 @@ import abc
import six import six
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _
from keystoneclient import utils from keystoneclient import utils
@@ -36,7 +37,7 @@ class ServiceCatalog(object):
elif ServiceCatalogV2.is_valid(resource_dict): elif ServiceCatalogV2.is_valid(resource_dict):
return ServiceCatalogV2(resource_dict, region_name) return ServiceCatalogV2(resource_dict, region_name)
else: else:
raise NotImplementedError('Unrecognized auth response') raise NotImplementedError(_('Unrecognized auth response'))
def __init__(self, region_name=None): def __init__(self, region_name=None):
self._region_name = region_name self._region_name = region_name
@@ -208,7 +209,7 @@ class ServiceCatalog(object):
""" """
if not self.get_data(): if not self.get_data():
raise exceptions.EmptyCatalog('The service catalog is empty.') raise exceptions.EmptyCatalog(_('The service catalog is empty.'))
urls = self.get_urls(attr=attr, urls = self.get_urls(attr=attr,
filter_value=filter_value, filter_value=filter_value,
@@ -222,12 +223,30 @@ class ServiceCatalog(object):
except Exception: except Exception:
pass pass
msg = '%s endpoint for %s service' % (endpoint_type, service_type) if service_name and region_name:
if service_name: msg = (_('%(endpoint_type)s endpoint for %(service_type)s service '
msg += ' named %s' % service_name 'named %(service_name)s in %(region_name)s region not '
if region_name: 'found') %
msg += ' in %s region' % region_name {'endpoint_type': endpoint_type,
msg += ' not found' 'service_type': service_type, 'service_name': service_name,
'region_name': region_name})
elif service_name:
msg = (_('%(endpoint_type)s endpoint for %(service_type)s service '
'named %(service_name)s not found') %
{'endpoint_type': endpoint_type,
'service_type': service_type,
'service_name': service_name})
elif region_name:
msg = (_('%(endpoint_type)s endpoint for %(service_type)s service '
'in %(region_name)s region not found') %
{'endpoint_type': endpoint_type,
'service_type': service_type, 'region_name': region_name})
else:
msg = (_('%(endpoint_type)s endpoint for %(service_type)s service '
'not found') %
{'endpoint_type': endpoint_type,
'service_type': service_type})
raise exceptions.EndpointNotFound(msg) raise exceptions.EndpointNotFound(msg)
@abc.abstractmethod @abc.abstractmethod

View File

@@ -25,6 +25,7 @@ import six
from six.moves import urllib from six.moves import urllib
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _, _LI, _LW
from keystoneclient import utils from keystoneclient import utils
osprofiler_web = importutils.try_import("osprofiler.web") osprofiler_web = importutils.try_import("osprofiler.web")
@@ -40,10 +41,10 @@ def _positive_non_zero_float(argument_value):
try: try:
value = float(argument_value) value = float(argument_value)
except ValueError: except ValueError:
msg = "%s must be a float" % argument_value msg = _("%s must be a float") % argument_value
raise argparse.ArgumentTypeError(msg) raise argparse.ArgumentTypeError(msg)
if value <= 0: if value <= 0:
msg = "%s must be greater than 0" % argument_value msg = _("%s must be greater than 0") % argument_value
raise argparse.ArgumentTypeError(msg) raise argparse.ArgumentTypeError(msg)
return value return value
@@ -274,7 +275,7 @@ class Session(object):
token = self.get_token(auth) token = self.get_token(auth)
if not token: if not token:
raise exceptions.AuthorizationFailure("No token Available") raise exceptions.AuthorizationFailure(_("No token Available"))
headers['X-Auth-Token'] = token headers['X-Auth-Token'] = token
@@ -372,20 +373,20 @@ class Session(object):
try: try:
resp = self.session.request(method, url, **kwargs) resp = self.session.request(method, url, **kwargs)
except requests.exceptions.SSLError: except requests.exceptions.SSLError:
msg = 'SSL exception connecting to %s' % url msg = _('SSL exception connecting to %s') % url
raise exceptions.SSLError(msg) raise exceptions.SSLError(msg)
except requests.exceptions.Timeout: except requests.exceptions.Timeout:
msg = 'Request to %s timed out' % url msg = _('Request to %s timed out') % url
raise exceptions.RequestTimeout(msg) raise exceptions.RequestTimeout(msg)
except requests.exceptions.ConnectionError: except requests.exceptions.ConnectionError:
msg = 'Unable to establish connection to %s' % url msg = _('Unable to establish connection to %s') % url
raise exceptions.ConnectionRefused(msg) raise exceptions.ConnectionRefused(msg)
except (exceptions.RequestTimeout, exceptions.ConnectionRefused) as e: except (exceptions.RequestTimeout, exceptions.ConnectionRefused) as e:
if connect_retries <= 0: if connect_retries <= 0:
raise raise
_logger.info('Failure: %s. Retrying in %.1fs.', _logger.info(_LI('Failure: %(e)s. Retrying in %(delay).1fs.'),
e, connect_retry_delay) {'e': e, 'delay': connect_retry_delay})
time.sleep(connect_retry_delay) time.sleep(connect_retry_delay)
return self._send_request( return self._send_request(
@@ -411,8 +412,8 @@ class Session(object):
try: try:
location = resp.headers['location'] location = resp.headers['location']
except KeyError: except KeyError:
_logger.warn("Failed to redirect request to %s as new " _logger.warn(_LW("Failed to redirect request to %s as new "
"location was not provided.", resp.url) "location was not provided."), resp.url)
else: else:
# NOTE(jamielennox): We don't pass through connect_retry_delay. # NOTE(jamielennox): We don't pass through connect_retry_delay.
# This request actually worked so we can reset the delay count. # This request actually worked so we can reset the delay count.
@@ -508,13 +509,13 @@ class Session(object):
auth = self.auth auth = self.auth
if not auth: if not auth:
raise exceptions.MissingAuthPlugin("Token Required") raise exceptions.MissingAuthPlugin(_("Token Required"))
try: try:
return auth.get_token(self) return auth.get_token(self)
except exceptions.HttpError as exc: except exceptions.HttpError as exc:
raise exceptions.AuthorizationFailure("Authentication failure: " raise exceptions.AuthorizationFailure(
"%s" % exc) _("Authentication failure: %s") % exc)
def get_endpoint(self, auth=None, **kwargs): def get_endpoint(self, auth=None, **kwargs):
"""Get an endpoint as provided by the auth plugin. """Get an endpoint as provided by the auth plugin.
@@ -531,8 +532,9 @@ class Session(object):
auth = self.auth auth = self.auth
if not auth: if not auth:
raise exceptions.MissingAuthPlugin('An auth plugin is required to ' raise exceptions.MissingAuthPlugin(
'determine the endpoint URL.') _('An auth plugin is required to determine the endpoint '
'URL.'))
return auth.get_endpoint(self, **kwargs) return auth.get_endpoint(self, **kwargs)
@@ -543,7 +545,7 @@ class Session(object):
auth = self.auth auth = self.auth
if not auth: if not auth:
msg = 'Auth plugin not available to invalidate' msg = _('Auth plugin not available to invalidate')
raise exceptions.MissingAuthPlugin(msg) raise exceptions.MissingAuthPlugin(msg)
return auth.invalidate() return auth.invalidate()

View File

@@ -9,6 +9,7 @@ Babel>=1.3
iso8601>=0.1.9 iso8601>=0.1.9
netaddr>=0.7.12 netaddr>=0.7.12
oslo.config>=1.4.0 # Apache-2.0 oslo.config>=1.4.0 # Apache-2.0
oslo.i18n>=1.0.0 # Apache-2.0
oslo.serialization>=1.0.0 # Apache-2.0 oslo.serialization>=1.0.0 # Apache-2.0
oslo.utils>=1.0.0 # Apache-2.0 oslo.utils>=1.0.0 # Apache-2.0
PrettyTable>=0.7,<0.8 PrettyTable>=0.7,<0.8

View File

@@ -45,3 +45,6 @@ exclude = .venv,.tox,dist,doc,*egg,build,*openstack/common*
commands= commands=
python setup.py build_sphinx python setup.py build_sphinx
[hacking]
import_exceptions =
keystoneclient.i18n