Keystoneclient didn't provide translated messages. With this
change, the messages are marked for translation.

DocImpact

Implements: blueprint keystoneclient-i18n

Change-Id: I85263a71671a1dffed524185266e6bb7ae559630
This commit is contained in:
Brant Knudson
2014-10-27 10:54:48 -05:00
committed by Jamie Lennox
parent 3b766c5143
commit fece74ca3e
33 changed files with 293 additions and 186 deletions

View File

@@ -25,6 +25,7 @@ import logging
import re import re
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _, _LI, _LW
from keystoneclient import utils from keystoneclient import utils
@@ -65,7 +66,7 @@ def get_version_data(session, url, authenticated=None):
pass pass
err_text = resp.text[:50] + '...' if len(resp.text) > 50 else resp.text err_text = resp.text[:50] + '...' if len(resp.text) > 50 else resp.text
msg = 'Invalid Response - Bad version data returned: %s' % err_text msg = _('Invalid Response - Bad version data returned: %s') % err_text
raise exceptions.DiscoveryFailure(msg) raise exceptions.DiscoveryFailure(msg)
@@ -99,7 +100,7 @@ def normalize_version_number(version):
except Exception: except Exception:
pass pass
raise TypeError('Invalid version specified: %s' % version) raise TypeError(_('Invalid version specified: %s') % version)
def version_match(required, candidate): def version_match(required, candidate):
@@ -159,8 +160,8 @@ class Discover(object):
try: try:
status = v['status'] status = v['status']
except KeyError: except KeyError:
_LOGGER.warning('Skipping over invalid version data. ' _LOGGER.warning(_LW('Skipping over invalid version data. '
'No stability status in version.') 'No stability status in version.'))
continue continue
status = status.lower() status = status.lower()
@@ -198,13 +199,14 @@ class Discover(object):
try: try:
version_str = v['id'] version_str = v['id']
except KeyError: except KeyError:
_LOGGER.info('Skipping invalid version data. Missing ID.') _LOGGER.info(_LI('Skipping invalid version data. Missing ID.'))
continue continue
try: try:
links = v['links'] links = v['links']
except KeyError: except KeyError:
_LOGGER.info('Skipping invalid version data. Missing links') _LOGGER.info(
_LI('Skipping invalid version data. Missing links'))
continue continue
version_number = normalize_version_number(version_str) version_number = normalize_version_number(version_str)
@@ -214,15 +216,15 @@ class Discover(object):
rel = link['rel'] rel = link['rel']
url = link['href'] url = link['href']
except (KeyError, TypeError): except (KeyError, TypeError):
_LOGGER.info('Skipping invalid version link. ' _LOGGER.info(_LI('Skipping invalid version link. '
'Missing link URL or relationship.') 'Missing link URL or relationship.'))
continue continue
if rel.lower() == 'self': if rel.lower() == 'self':
break break
else: else:
_LOGGER.info('Skipping invalid version data. ' _LOGGER.info(_LI('Skipping invalid version data. '
'Missing link to endpoint.') 'Missing link to endpoint.'))
continue continue
versions.append({'version': version_number, versions.append({'version': version_number,

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

@@ -27,6 +27,7 @@ from six.moves import urllib
from keystoneclient import auth from keystoneclient import auth
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _
from keystoneclient.openstack.common.apiclient import base from keystoneclient.openstack.common.apiclient import base
@@ -219,7 +220,7 @@ class Manager(object):
management=management, management=management,
**kwargs) **kwargs)
except KeyError: except KeyError:
raise exceptions.ClientException("Invalid update method: %s" raise exceptions.ClientException(_("Invalid update method: %s")
% method) % method)
# PUT requests may not return a body # PUT requests may not return a body
if body: if body:
@@ -244,7 +245,8 @@ class ManagerWithFind(Manager):
num = len(rl) num = len(rl)
if num == 0: if num == 0:
msg = "No %s matching %s." % (self.resource_class.__name__, kwargs) msg = _("No %(name)s matching %(kwargs)s.") % {
'name': self.resource_class.__name__, 'kwargs': kwargs}
raise exceptions.NotFound(404, msg) raise exceptions.NotFound(404, msg)
elif num > 1: elif num > 1:
raise exceptions.NoUniqueMatch raise exceptions.NoUniqueMatch
@@ -395,7 +397,8 @@ class CrudManager(Manager):
num = len(rl) num = len(rl)
if num == 0: if num == 0:
msg = "No %s matching %s." % (self.resource_class.__name__, kwargs) msg = _("No %(name)s matching %(kwargs)s.") % {
'name': self.resource_class.__name__, 'kwargs': kwargs}
raise exceptions.NotFound(404, msg) raise exceptions.NotFound(404, msg)
elif num > 1: elif num > 1:
raise exceptions.NoUniqueMatch raise exceptions.NoUniqueMatch

View File

@@ -28,6 +28,7 @@ import zlib
import six import six
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _, _LE, _LW
subprocess = None subprocess = None
@@ -73,8 +74,9 @@ def _check_files_accessible(files):
except IOError as e: except IOError as e:
# Catching IOError means there is an issue with # Catching IOError means there is an issue with
# the given file. # the given file.
err = ('Hit OSError in _process_communicate_handle_oserror()\n' err = _('Hit OSError in _process_communicate_handle_oserror()\n'
'Likely due to %s: %s') % (try_file, e.strerror) 'Likely due to %(file)s: %(error)s') % {'file': try_file,
'error': e.strerror}
# Emulate openssl behavior, which returns with code 2 when # Emulate openssl behavior, which returns with code 2 when
# access to a file failed: # access to a file failed:
@@ -122,8 +124,9 @@ def _encoding_for_form(inform):
elif inform == PKIZ_CMS_FORM: elif inform == PKIZ_CMS_FORM:
encoding = 'hex' encoding = 'hex'
else: else:
raise ValueError('"inform" must be either %s or %s' % raise ValueError(
(PKI_ASN1_FORM, PKIZ_CMS_FORM)) _('"inform" must be one of: %s') % ','.join((PKI_ASN1_FORM,
PKIZ_CMS_FORM)))
return encoding return encoding
@@ -296,8 +299,8 @@ def is_asn1_token(token):
def is_ans1_token(token): def is_ans1_token(token):
"""Deprecated. Use is_asn1_token() instead.""" """Deprecated. Use is_asn1_token() instead."""
LOG.warning('The function is_ans1_token() is deprecated, ' LOG.warning(_LW('The function is_ans1_token() is deprecated, '
'use is_asn1_token() instead.') 'use is_asn1_token() instead.'))
return is_asn1_token(token) return is_asn1_token(token)
@@ -344,13 +347,13 @@ def cms_sign_data(data_to_sign, signing_cert_file_name, signing_key_file_name,
process, data, (signing_cert_file_name, signing_key_file_name)) process, data, (signing_cert_file_name, signing_key_file_name))
if retcode or ('Error' in err): if retcode or ('Error' in err):
LOG.error('Signing error: %s', err) LOG.error(_LE('Signing error: %s'), err)
if retcode == 3: if retcode == 3:
LOG.error('Signing error: Unable to load certificate - ' LOG.error(_LE('Signing error: Unable to load certificate - '
'ensure you have configured PKI with ' 'ensure you have configured PKI with '
'"keystone-manage pki_setup"') '"keystone-manage pki_setup"'))
else: else:
LOG.error('Signing error: %s', err) LOG.error(_LE('Signing error: %s'), err)
raise subprocess.CalledProcessError(retcode, 'openssl') raise subprocess.CalledProcessError(retcode, 'openssl')
if outform == PKI_ASN1_FORM: if outform == PKI_ASN1_FORM:
return output.decode('utf-8') return output.decode('utf-8')

View File

@@ -20,6 +20,7 @@ from six.moves import urllib
from keystoneclient import access from keystoneclient import access
from keystoneclient.auth.identity import v3 from keystoneclient.auth.identity import v3
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _
class _BaseSAMLPlugin(v3.AuthConstructor): class _BaseSAMLPlugin(v3.AuthConstructor):
@@ -30,7 +31,7 @@ class _BaseSAMLPlugin(v3.AuthConstructor):
@staticmethod @staticmethod
def _first(_list): def _first(_list):
if len(_list) != 1: if len(_list) != 1:
raise IndexError("Only single element list is acceptable") raise IndexError(_("Only single element list is acceptable"))
return _list[0] return _list[0]
@staticmethod @staticmethod
@@ -80,8 +81,8 @@ class Saml2UnscopedTokenAuthMethod(v3.AuthMethod):
_method_parameters = [] _method_parameters = []
def get_auth_data(self, session, auth, headers, **kwargs): def get_auth_data(self, session, auth, headers, **kwargs):
raise exceptions.MethodNotImplemented(('This method should never ' raise exceptions.MethodNotImplemented(_('This method should never '
'be called')) 'be called'))
class Saml2UnscopedToken(_BaseSAMLPlugin): class Saml2UnscopedToken(_BaseSAMLPlugin):
@@ -211,9 +212,9 @@ class Saml2UnscopedToken(_BaseSAMLPlugin):
authenticated=False) authenticated=False)
# prepare error message and raise an exception. # prepare error message and raise an exception.
msg = ("Consumer URLs from Service Provider %(service_provider)s " msg = _("Consumer URLs from Service Provider %(service_provider)s "
"%(sp_consumer_url)s and Identity Provider " "%(sp_consumer_url)s and Identity Provider "
"%(identity_provider)s %(idp_consumer_url)s are not equal") "%(identity_provider)s %(idp_consumer_url)s are not equal")
msg = msg % { msg = msg % {
'service_provider': self.token_url, 'service_provider': self.token_url,
'sp_consumer_url': sp_response_consumer_url, 'sp_consumer_url': sp_response_consumer_url,
@@ -257,8 +258,8 @@ class Saml2UnscopedToken(_BaseSAMLPlugin):
try: try:
self.saml2_authn_request = etree.XML(sp_response.content) self.saml2_authn_request = etree.XML(sp_response.content)
except etree.XMLSyntaxError as e: except etree.XMLSyntaxError as e:
msg = ("SAML2: Error parsing XML returned " msg = _("SAML2: Error parsing XML returned "
"from Service Provider, reason: %s" % e) "from Service Provider, reason: %s") % e
raise exceptions.AuthorizationFailure(msg) raise exceptions.AuthorizationFailure(msg)
relay_state = self.saml2_authn_request.xpath( relay_state = self.saml2_authn_request.xpath(
@@ -288,8 +289,8 @@ class Saml2UnscopedToken(_BaseSAMLPlugin):
try: try:
self.saml2_idp_authn_response = etree.XML(idp_response.content) self.saml2_idp_authn_response = etree.XML(idp_response.content)
except etree.XMLSyntaxError as e: except etree.XMLSyntaxError as e:
msg = ("SAML2: Error parsing XML returned " msg = _("SAML2: Error parsing XML returned "
"from Identity Provider, reason: %s" % e) "from Identity Provider, reason: %s") % e
raise exceptions.AuthorizationFailure(msg) raise exceptions.AuthorizationFailure(msg)
idp_response_consumer_url = self.saml2_idp_authn_response.xpath( idp_response_consumer_url = self.saml2_idp_authn_response.xpath(
@@ -736,8 +737,8 @@ class ADFSUnscopedToken(_BaseSAMLPlugin):
except exceptions.InternalServerError as e: except exceptions.InternalServerError as e:
reason = _get_failure(e) reason = _get_failure(e)
raise exceptions.AuthorizationFailure(reason) raise exceptions.AuthorizationFailure(reason)
msg = ("Error parsing XML returned from " msg = _("Error parsing XML returned from "
"the ADFS Identity Provider, reason: %s") "the ADFS Identity Provider, reason: %s")
self.adfs_token = self.str_to_xml(response.content, msg) self.adfs_token = self.str_to_xml(response.content, msg)
def _prepare_sp_request(self): def _prepare_sp_request(self):
@@ -803,8 +804,9 @@ class ADFSUnscopedToken(_BaseSAMLPlugin):
""" """
if self._cookies(session) is False: if self._cookies(session) is False:
raise exceptions.AuthorizationFailure( raise exceptions.AuthorizationFailure(
"Session object doesn't contain a cookie, therefore you are " _("Session object doesn't contain a cookie, therefore you are "
"not allowed to enter the Identity Provider's protected area.") "not allowed to enter the Identity Provider's protected "
"area."))
self.authenticated_response = session.get(self.token_url, self.authenticated_response = session.get(self.token_url,
authenticated=False) authenticated=False)
@@ -883,4 +885,4 @@ class Saml2ScopedToken(v3.Token):
super(Saml2ScopedToken, self).__init__(auth_url, token, **kwargs) super(Saml2ScopedToken, self).__init__(auth_url, token, **kwargs)
if not (self.project_id or self.domain_id): if not (self.project_id or self.domain_id):
raise exceptions.ValidationError( raise exceptions.ValidationError(
'Neither project nor domain specified') _('Neither project nor domain specified'))

View File

@@ -24,6 +24,8 @@ import re
import six import six
from six.moves import urllib from six.moves import urllib
from keystoneclient.i18n import _
class Ec2Signer(object): class Ec2Signer(object):
"""Utility class which adds allows a request to be signed with an AWS style """Utility class which adds allows a request to be signed with an AWS style
@@ -91,10 +93,10 @@ class Ec2Signer(object):
credentials['body_hash']) credentials['body_hash'])
if signature_version is not None: if signature_version is not None:
raise Exception('Unknown signature version: %s' % raise Exception(_('Unknown signature version: %s') %
signature_version) signature_version)
else: else:
raise Exception('Unexpected signature format') raise Exception(_('Unexpected signature format'))
@staticmethod @staticmethod
def _get_utf8_value(value): def _get_utf8_value(value):
@@ -257,7 +259,7 @@ class Ec2Signer(object):
credential_date = credential_split[1] credential_date = credential_split[1]
param_date = date_param() param_date = date_param()
if not param_date.startswith(credential_date): if not param_date.startswith(credential_date):
raise Exception('Request date mismatch error') raise Exception(_('Request date mismatch error'))
# Create the string to sign # Create the string to sign
# http://docs.aws.amazon.com/general/latest/gr/ # http://docs.aws.amazon.com/general/latest/gr/

View File

@@ -16,6 +16,7 @@ import six
from keystoneclient import _discover from keystoneclient import _discover
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _
from keystoneclient import session as client_session from keystoneclient import session as client_session
from keystoneclient import utils from keystoneclient import utils
from keystoneclient.v2_0 import client as v2_client from keystoneclient.v2_0 import client as v2_client
@@ -122,9 +123,9 @@ class Discover(_discover.Discover):
url = auth_url url = auth_url
if not url: if not url:
raise exceptions.DiscoveryFailure('Not enough information to ' raise exceptions.DiscoveryFailure(
'determine URL. Provide either ' _('Not enough information to determine URL. Provide either '
'auth_url or endpoint') 'auth_url or endpoint'))
self._client_kwargs = kwargs self._client_kwargs = kwargs
super(Discover, self).__init__(session, url, super(Discover, self).__init__(session, url,
@@ -213,10 +214,11 @@ class Discover(_discover.Discover):
version_data = all_versions[-1] version_data = all_versions[-1]
if not version_data: if not version_data:
msg = 'Could not find a suitable endpoint' msg = _('Could not find a suitable endpoint')
if version: if version:
msg += ' for client version: %s' % str(version) msg = _('Could not find a suitable endpoint for client '
'version: %s') % str(version)
raise exceptions.VersionNotAvailable(msg) raise exceptions.VersionNotAvailable(msg)
@@ -228,7 +230,7 @@ class Discover(_discover.Discover):
client_class = _CLIENT_VERSIONS[version_data['version'][0]] client_class = _CLIENT_VERSIONS[version_data['version'][0]]
except KeyError: except KeyError:
version = '.'.join(str(v) for v in version_data['version']) version = '.'.join(str(v) for v in version_data['version'])
msg = 'No client available for version: %s' % version msg = _('No client available for version: %s') % version
raise exceptions.DiscoveryFailure(msg) raise exceptions.DiscoveryFailure(msg)
# kwargs should take priority over stored kwargs. # kwargs should take priority over stored kwargs.

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)

View File

@@ -19,6 +19,7 @@ from six.moves.urllib import parse as urlparse
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient import httpclient from keystoneclient import httpclient
from keystoneclient.i18n import _
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@@ -94,7 +95,7 @@ class Client(httpclient.HTTPClient):
try: try:
results = {} results = {}
if 'version' in body: if 'version' in body:
results['message'] = "Keystone found at %s" % url results['message'] = _("Keystone found at %s") % url
version = body['version'] version = body['version']
# Stable/diablo incorrect format # Stable/diablo incorrect format
id, status, version_url = ( id, status, version_url = (
@@ -105,7 +106,7 @@ class Client(httpclient.HTTPClient):
return results return results
elif 'versions' in body: elif 'versions' in body:
# Correct format # Correct format
results['message'] = "Keystone found at %s" % url results['message'] = _("Keystone found at %s") % url
for version in body['versions']['values']: for version in body['versions']['values']:
id, status, version_url = ( id, status, version_url = (
self._get_version_info(version, url)) self._get_version_info(version, url))
@@ -114,8 +115,8 @@ class Client(httpclient.HTTPClient):
"url": version_url} "url": version_url}
return results return results
else: else:
results['message'] = ("Unrecognized response from %s" results['message'] = (
% url) _("Unrecognized response from %s") % url)
return results return results
except KeyError: except KeyError:
raise exceptions.AuthorizationFailure() raise exceptions.AuthorizationFailure()
@@ -159,7 +160,7 @@ class Client(httpclient.HTTPClient):
extensions = body['extensions'] extensions = body['extensions']
else: else:
return dict(message=( return dict(message=(
'Unrecognized extensions response from %s' % url)) _('Unrecognized extensions response from %s') % url))
return dict(self._get_extension_info(e) for e in extensions) return dict(self._get_extension_info(e) for e in extensions)
elif resp.status_code == 305: elif resp.status_code == 305:

View File

@@ -16,6 +16,7 @@
import six import six
from keystoneclient.generic import client from keystoneclient.generic import client
from keystoneclient.i18n import _
from keystoneclient import utils from keystoneclient import utils
@@ -37,13 +38,14 @@ def do_discover(cs, args):
print(versions['message']) print(versions['message'])
for key, version in six.iteritems(versions): for key, version in six.iteritems(versions):
if key != 'message': if key != 'message':
print(" - supports version %s (%s) here %s" % print(_(" - supports version %(id)s (%(status)s) here "
(version['id'], version['status'], version['url'])) "%(url)s") %
version)
extensions = cs.discover_extensions(version['url']) extensions = cs.discover_extensions(version['url'])
if extensions: if extensions:
for key, extension in six.iteritems(extensions): for key, extension in six.iteritems(extensions):
if key != 'message': if key != 'message':
print(" - and %s: %s" % print(_(" - and %(key)s: %(extension)s") %
(key, extension)) {'key': key, 'extension': extension})
else: else:
print("No Keystone-compatible endpoint found") print(_("No Keystone-compatible endpoint found"))

View File

@@ -55,6 +55,7 @@ from keystoneclient import access
from keystoneclient.auth import base from keystoneclient.auth import base
from keystoneclient import baseclient from keystoneclient import baseclient
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _, _LI, _LW
from keystoneclient import session as client_session from keystoneclient import session as client_session
from keystoneclient import utils from keystoneclient import utils
@@ -265,7 +266,7 @@ class HTTPClient(baseclient.Client, base.BaseAuthPlugin):
# keyring setup # keyring setup
if use_keyring and keyring is None: if use_keyring and keyring is None:
_logger.warning('Failed to load keyring modules.') _logger.warning(_LW('Failed to load keyring modules.'))
self.use_keyring = use_keyring and keyring is not None self.use_keyring = use_keyring and keyring is not None
self.force_new_token = force_new_token self.force_new_token = force_new_token
self.stale_duration = stale_duration or access.STALE_TOKEN_DURATION self.stale_duration = stale_duration or access.STALE_TOKEN_DURATION
@@ -476,7 +477,8 @@ class HTTPClient(baseclient.Client, base.BaseAuthPlugin):
auth_ref = None auth_ref = None
except Exception as e: except Exception as e:
auth_ref = None auth_ref = None
_logger.warning('Unable to retrieve token from keyring %s', e) _logger.warning(
_LW('Unable to retrieve token from keyring %s'), e)
return (keyring_key, auth_ref) return (keyring_key, auth_ref)
def store_auth_ref_into_keyring(self, keyring_key): def store_auth_ref_into_keyring(self, keyring_key):
@@ -489,7 +491,8 @@ class HTTPClient(baseclient.Client, base.BaseAuthPlugin):
keyring_key, keyring_key,
pickle.dumps(self.auth_ref)) pickle.dumps(self.auth_ref))
except Exception as e: except Exception as e:
_logger.warning("Failed to store token into keyring %s", e) _logger.warning(
_LW("Failed to store token into keyring %s"), e)
def _process_management_url(self, region_name): def _process_management_url(self, region_name):
try: try:
@@ -511,14 +514,14 @@ class HTTPClient(baseclient.Client, base.BaseAuthPlugin):
if self.auth_ref.project_scoped: if self.auth_ref.project_scoped:
if not self.auth_ref.tenant_id: if not self.auth_ref.tenant_id:
raise exceptions.AuthorizationFailure( raise exceptions.AuthorizationFailure(
"Token didn't provide tenant_id") _("Token didn't provide tenant_id"))
self._process_management_url(region_name) self._process_management_url(region_name)
self.project_name = self.auth_ref.tenant_name self.project_name = self.auth_ref.tenant_name
self.project_id = self.auth_ref.tenant_id self.project_id = self.auth_ref.tenant_id
if not self.auth_ref.user_id: if not self.auth_ref.user_id:
raise exceptions.AuthorizationFailure( raise exceptions.AuthorizationFailure(
"Token didn't provide user_id") _("Token didn't provide user_id"))
self.user_id = self.auth_ref.user_id self.user_id = self.auth_ref.user_id
@@ -620,10 +623,11 @@ class HTTPClient(baseclient.Client, base.BaseAuthPlugin):
try: try:
return self.request(url, method, **kwargs) return self.request(url, method, **kwargs)
except exceptions.MissingAuthPlugin: except exceptions.MissingAuthPlugin:
_logger.info('Cannot get authenticated endpoint without an ' _logger.info(_LI('Cannot get authenticated endpoint without an '
'auth plugin') 'auth plugin'))
raise exceptions.AuthorizationFailure( raise exceptions.AuthorizationFailure(
'Current authorization does not have a known management url') _('Current authorization does not have a known management '
'url'))
def get(self, url, **kwargs): def get(self, url, **kwargs):
return self._cs_request(url, 'GET', **kwargs) return self._cs_request(url, 'GET', **kwargs)
@@ -656,7 +660,7 @@ class HTTPClient(baseclient.Client, base.BaseAuthPlugin):
try: try:
var_name = self.deprecated_session_variables[name] var_name = self.deprecated_session_variables[name]
except KeyError: except KeyError:
raise AttributeError("Unknown Attribute: %s" % name) raise AttributeError(_("Unknown Attribute: %s") % name)
return getattr(self.session, var_name or name) return getattr(self.session, var_name or name)

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

@@ -18,6 +18,7 @@ import logging
from keystoneclient.auth.identity import v2 as v2_auth from keystoneclient.auth.identity import v2 as v2_auth
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient import httpclient from keystoneclient import httpclient
from keystoneclient.i18n import _
from keystoneclient.v2_0 import ec2 from keystoneclient.v2_0 import ec2
from keystoneclient.v2_0 import endpoints from keystoneclient.v2_0 import endpoints
from keystoneclient.v2_0 import extensions from keystoneclient.v2_0 import extensions
@@ -163,7 +164,7 @@ class Client(httpclient.HTTPClient):
""" """
try: try:
if auth_url is None: if auth_url is None:
raise ValueError("Cannot authenticate without an auth_url") raise ValueError(_("Cannot authenticate without an auth_url"))
new_kwargs = {'trust_id': trust_id, new_kwargs = {'trust_id': trust_id,
'tenant_id': project_id or tenant_id, 'tenant_id': project_id or tenant_id,
@@ -175,7 +176,7 @@ class Client(httpclient.HTTPClient):
plugin = v2_auth.Password(auth_url, username, password, plugin = v2_auth.Password(auth_url, username, password,
**new_kwargs) **new_kwargs)
else: else:
msg = 'A username and password or token is required.' msg = _('A username and password or token is required.')
raise exceptions.AuthorizationFailure(msg) raise exceptions.AuthorizationFailure(msg)
return plugin.get_auth_ref(self.session) return plugin.get_auth_ref(self.session)
@@ -183,8 +184,9 @@ class Client(httpclient.HTTPClient):
_logger.debug("Authorization Failed.") _logger.debug("Authorization Failed.")
raise raise
except exceptions.EndpointNotFound: except exceptions.EndpointNotFound:
msg = 'There was no suitable authentication url for this request' msg = (
_('There was no suitable authentication url for this request'))
raise exceptions.AuthorizationFailure(msg) raise exceptions.AuthorizationFailure(msg)
except Exception as e: except Exception as e:
raise exceptions.AuthorizationFailure("Authorization Failed: " raise exceptions.AuthorizationFailure(
"%s" % e) _("Authorization Failed: %s") % e)

View File

@@ -29,6 +29,7 @@ import sys
from oslo.utils import strutils from oslo.utils import strutils
import six import six
from keystoneclient.i18n import _
from keystoneclient import utils from keystoneclient import utils
from keystoneclient.v2_0 import client from keystoneclient.v2_0 import client
@@ -38,9 +39,9 @@ ASK_FOR_PASSWORD = object()
def require_service_catalog(f): def require_service_catalog(f):
msg = ('Configuration error: Client configured to run without a service ' msg = _('Configuration error: Client configured to run without a service '
'catalog. Run the client using --os-auth-url or OS_AUTH_URL, ' 'catalog. Run the client using --os-auth-url or OS_AUTH_URL, '
'instead of --os-endpoint or OS_SERVICE_ENDPOINT, for example.') 'instead of --os-endpoint or OS_SERVICE_ENDPOINT, for example.')
def wrapped(kc, args): def wrapped(kc, args):
if not kc.has_service_catalog(): if not kc.has_service_catalog():
@@ -121,15 +122,15 @@ def do_user_update(kc, args):
kwargs['enabled'] = strutils.bool_from_string(args.enabled) kwargs['enabled'] = strutils.bool_from_string(args.enabled)
if not len(kwargs): if not len(kwargs):
print("User not updated, no arguments present.") print(_("User not updated, no arguments present."))
return return
user = utils.find_resource(kc.users, args.user) user = utils.find_resource(kc.users, args.user)
try: try:
kc.users.update(user, **kwargs) kc.users.update(user, **kwargs)
print('User has been updated.') print(_('User has been updated.'))
except Exception as e: except Exception as e:
print('Unable to update user: %s' % e) print(_('Unable to update user: %s') % e)
@utils.arg('--pass', metavar='<password>', dest='passwd', required=False, @utils.arg('--pass', metavar='<password>', dest='passwd', required=False,
@@ -141,8 +142,8 @@ def do_user_password_update(kc, args):
user = utils.find_resource(kc.users, args.user) user = utils.find_resource(kc.users, args.user)
new_passwd = args.passwd or utils.prompt_for_password() new_passwd = args.passwd or utils.prompt_for_password()
if new_passwd is None: if new_passwd is None:
msg = ("\nPlease specify password using the --pass option " msg = (_("\nPlease specify password using the --pass option "
"or using the prompt") "or using the prompt"))
sys.exit(msg) sys.exit(msg)
kc.users.update_password(user, new_passwd) kc.users.update_password(user, new_passwd)
@@ -163,20 +164,20 @@ def do_password_update(kc, args):
if args.currentpasswd is not None: if args.currentpasswd is not None:
currentpasswd = args.currentpasswd currentpasswd = args.currentpasswd
if currentpasswd is None: if currentpasswd is None:
currentpasswd = getpass.getpass('Current Password: ') currentpasswd = getpass.getpass(_('Current Password: '))
newpasswd = args.newpasswd newpasswd = args.newpasswd
while newpasswd is None: while newpasswd is None:
passwd1 = getpass.getpass('New Password: ') passwd1 = getpass.getpass(_('New Password: '))
passwd2 = getpass.getpass('Repeat New Password: ') passwd2 = getpass.getpass(_('Repeat New Password: '))
if passwd1 == passwd2: if passwd1 == passwd2:
newpasswd = passwd1 newpasswd = passwd1
kc.users.update_own_password(currentpasswd, newpasswd) kc.users.update_own_password(currentpasswd, newpasswd)
if args.os_password != newpasswd: if args.os_password != newpasswd:
print("You should update the password you are using to authenticate " print(_("You should update the password you are using to authenticate "
"to match your new password") "to match your new password"))
@utils.arg('user', metavar='<user>', help='Name or ID of user to delete.') @utils.arg('user', metavar='<user>', help='Name or ID of user to delete.')
@@ -234,7 +235,7 @@ def do_tenant_update(kc, args):
kwargs.update({'enabled': strutils.bool_from_string(args.enabled)}) kwargs.update({'enabled': strutils.bool_from_string(args.enabled)})
if kwargs == {}: if kwargs == {}:
print("Tenant not updated, no arguments present.") print(_("Tenant not updated, no arguments present."))
return return
tenant.update(**kwargs) tenant.update(**kwargs)
@@ -450,9 +451,9 @@ def do_ec2_credentials_delete(kc, args):
args.user_id = kc.auth_user_id args.user_id = kc.auth_user_id
try: try:
kc.ec2.delete(args.user_id, args.access) kc.ec2.delete(args.user_id, args.access)
print('Credential has been deleted.') print(_('Credential has been deleted.'))
except Exception as e: except Exception as e:
print('Unable to delete credential: %s' % e) print(_('Unable to delete credential: %s') % e)
@utils.arg('--service', metavar='<service-type>', default=None, @utils.arg('--service', metavar='<service-type>', default=None,
@@ -463,7 +464,7 @@ def do_catalog(kc, args):
endpoints = kc.service_catalog.get_endpoints(service_type=args.service) endpoints = kc.service_catalog.get_endpoints(service_type=args.service)
for (service, service_endpoints) in six.iteritems(endpoints): for (service, service_endpoints) in six.iteritems(endpoints):
if len(service_endpoints) > 0: if len(service_endpoints) > 0:
print("Service: %s" % service) print(_("Service: %s") % service)
for ep in service_endpoints: for ep in service_endpoints:
utils.print_dict(ep) utils.print_dict(ep)
@@ -489,7 +490,7 @@ def do_endpoint_get(kc, args):
if args.attr and args.value: if args.attr and args.value:
kwargs.update({'attr': args.attr, 'filter_value': args.value}) kwargs.update({'attr': args.attr, 'filter_value': args.value})
elif args.attr or args.value: elif args.attr or args.value:
print('Both --attr and --value required.') print(_('Both --attr and --value required.'))
return return
url = kc.service_catalog.url_for(**kwargs) url = kc.service_catalog.url_for(**kwargs)
@@ -531,9 +532,9 @@ def do_endpoint_delete(kc, args):
"""Delete a service endpoint.""" """Delete a service endpoint."""
try: try:
kc.endpoints.delete(args.id) kc.endpoints.delete(args.id)
print('Endpoint has been deleted.') print(_('Endpoint has been deleted.'))
except Exception: except Exception:
print('Unable to delete endpoint.') print(_('Unable to delete endpoint.'))
@utils.arg('--wrap', metavar='<integer>', default=0, @utils.arg('--wrap', metavar='<integer>', default=0,

View File

@@ -13,6 +13,7 @@
from keystoneclient import auth from keystoneclient import auth
from keystoneclient import base from keystoneclient import base
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _
from keystoneclient import utils from keystoneclient import utils
@@ -45,7 +46,8 @@ class TokenManager(base.Manager):
params = {"auth": {"passwordCredentials": {"username": username, params = {"auth": {"passwordCredentials": {"username": username,
"password": password}}} "password": password}}}
else: else:
raise ValueError('A username and password or token is required.') raise ValueError(
_('A username and password or token is required.'))
if tenant_id: if tenant_id:
params['auth']['tenantId'] = tenant_id params['auth']['tenantId'] = tenant_id
elif tenant_name: elif tenant_name:

View File

@@ -20,6 +20,7 @@ from oslo.serialization import jsonutils
from keystoneclient.auth.identity import v3 as v3_auth from keystoneclient.auth.identity import v3 as v3_auth
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient import httpclient from keystoneclient import httpclient
from keystoneclient.i18n import _
from keystoneclient.v3.contrib import endpoint_filter from keystoneclient.v3.contrib import endpoint_filter
from keystoneclient.v3.contrib import endpoint_policy from keystoneclient.v3.contrib import endpoint_policy
from keystoneclient.v3.contrib import federation from keystoneclient.v3.contrib import federation
@@ -203,7 +204,7 @@ EndpointPolicyManager`
if self.auth_ref.domain_scoped: if self.auth_ref.domain_scoped:
if not self.auth_ref.domain_id: if not self.auth_ref.domain_id:
raise exceptions.AuthorizationFailure( raise exceptions.AuthorizationFailure(
"Token didn't provide domain_id") _("Token didn't provide domain_id"))
self._process_management_url(kwargs.get('region_name')) self._process_management_url(kwargs.get('region_name'))
self.domain_name = self.auth_ref.domain_name self.domain_name = self.auth_ref.domain_name
self.domain_id = self.auth_ref.domain_id self.domain_id = self.auth_ref.domain_id
@@ -235,7 +236,7 @@ EndpointPolicyManager`
""" """
try: try:
if auth_url is None: if auth_url is None:
raise ValueError("Cannot authenticate without an auth_url") raise ValueError(_("Cannot authenticate without an auth_url"))
auth_methods = [] auth_methods = []
@@ -251,7 +252,7 @@ EndpointPolicyManager`
auth_methods.append(m) auth_methods.append(m)
if not auth_methods: if not auth_methods:
msg = 'A user and password or token is required.' msg = _('A user and password or token is required.')
raise exceptions.AuthorizationFailure(msg) raise exceptions.AuthorizationFailure(msg)
plugin = v3_auth.Auth(auth_url, auth_methods, plugin = v3_auth.Auth(auth_url, auth_methods,
@@ -268,8 +269,9 @@ EndpointPolicyManager`
_logger.debug('Authorization failed.') _logger.debug('Authorization failed.')
raise raise
except exceptions.EndpointNotFound: except exceptions.EndpointNotFound:
msg = 'There was no suitable authentication url for this request' msg = _('There was no suitable authentication url for this'
' request')
raise exceptions.AuthorizationFailure(msg) raise exceptions.AuthorizationFailure(msg)
except Exception as e: except Exception as e:
raise exceptions.AuthorizationFailure('Authorization failed: ' raise exceptions.AuthorizationFailure(
'%s' % e) _('Authorization failed: %s') % e)

View File

@@ -14,6 +14,7 @@
from keystoneclient import base from keystoneclient import base
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _
class EndpointFilterManager(base.Manager): class EndpointFilterManager(base.Manager):
@@ -31,7 +32,7 @@ class EndpointFilterManager(base.Manager):
elif endpoint_id: elif endpoint_id:
api_path = '/endpoints/%s/projects' % (endpoint_id) api_path = '/endpoints/%s/projects' % (endpoint_id)
else: else:
msg = 'Must specify a project, an endpoint, or both' msg = _('Must specify a project, an endpoint, or both')
raise exceptions.ValidationError(msg) raise exceptions.ValidationError(msg)
return self.OS_EP_FILTER_EXT + api_path return self.OS_EP_FILTER_EXT + api_path
@@ -39,7 +40,7 @@ class EndpointFilterManager(base.Manager):
def add_endpoint_to_project(self, project, endpoint): def add_endpoint_to_project(self, project, endpoint):
"""Create a project-endpoint association.""" """Create a project-endpoint association."""
if not (project and endpoint): if not (project and endpoint):
raise ValueError('project and endpoint are required') raise ValueError(_('project and endpoint are required'))
base_url = self._build_base_url(project=project, base_url = self._build_base_url(project=project,
endpoint=endpoint) endpoint=endpoint)
@@ -48,7 +49,7 @@ class EndpointFilterManager(base.Manager):
def delete_endpoint_from_project(self, project, endpoint): def delete_endpoint_from_project(self, project, endpoint):
"""Remove a project-endpoint association.""" """Remove a project-endpoint association."""
if not (project and endpoint): if not (project and endpoint):
raise ValueError('project and endpoint are required') raise ValueError(_('project and endpoint are required'))
base_url = self._build_base_url(project=project, base_url = self._build_base_url(project=project,
endpoint=endpoint) endpoint=endpoint)
@@ -57,7 +58,7 @@ class EndpointFilterManager(base.Manager):
def check_endpoint_in_project(self, project, endpoint): def check_endpoint_in_project(self, project, endpoint):
"""Checks if project-endpoint association exist.""" """Checks if project-endpoint association exist."""
if not (project and endpoint): if not (project and endpoint):
raise ValueError('project and endpoint are required') raise ValueError(_('project and endpoint are required'))
base_url = self._build_base_url(project=project, base_url = self._build_base_url(project=project,
endpoint=endpoint) endpoint=endpoint)
@@ -66,7 +67,7 @@ class EndpointFilterManager(base.Manager):
def list_endpoints_for_project(self, project): def list_endpoints_for_project(self, project):
"""List all endpoints for a given project.""" """List all endpoints for a given project."""
if not project: if not project:
raise ValueError('project is required') raise ValueError(_('project is required'))
base_url = self._build_base_url(project=project) base_url = self._build_base_url(project=project)
return super(EndpointFilterManager, self)._list( return super(EndpointFilterManager, self)._list(
@@ -77,7 +78,7 @@ class EndpointFilterManager(base.Manager):
def list_projects_for_endpoint(self, endpoint): def list_projects_for_endpoint(self, endpoint):
"""List all projects for a given endpoint.""" """List all projects for a given endpoint."""
if not endpoint: if not endpoint:
raise ValueError('endpoint is required') raise ValueError(_('endpoint is required'))
base_url = self._build_base_url(endpoint=endpoint) base_url = self._build_base_url(endpoint=endpoint)
return super(EndpointFilterManager, self)._list( return super(EndpointFilterManager, self)._list(

View File

@@ -13,6 +13,7 @@
# under the License. # under the License.
from keystoneclient import base from keystoneclient import base
from keystoneclient.i18n import _
from keystoneclient.v3 import policies from keystoneclient.v3 import policies
@@ -24,7 +25,7 @@ class EndpointPolicyManager(base.Manager):
def _act_on_policy_association_for_endpoint( def _act_on_policy_association_for_endpoint(
self, policy, endpoint, action): self, policy, endpoint, action):
if not (policy and endpoint): if not (policy and endpoint):
raise ValueError('policy and endpoint are required') raise ValueError(_('policy and endpoint are required'))
policy_id = base.getid(policy) policy_id = base.getid(policy)
endpoint_id = base.getid(endpoint) endpoint_id = base.getid(endpoint)
@@ -52,7 +53,7 @@ class EndpointPolicyManager(base.Manager):
def _act_on_policy_association_for_service(self, policy, service, action): def _act_on_policy_association_for_service(self, policy, service, action):
if not (policy and service): if not (policy and service):
raise ValueError('policy and service are required') raise ValueError(_('policy and service are required'))
policy_id = base.getid(policy) policy_id = base.getid(policy)
service_id = base.getid(service) service_id = base.getid(service)
@@ -81,7 +82,7 @@ class EndpointPolicyManager(base.Manager):
def _act_on_policy_association_for_region_and_service( def _act_on_policy_association_for_region_and_service(
self, policy, region, service, action): self, policy, region, service, action):
if not (policy and region and service): if not (policy and region and service):
raise ValueError('policy, region and service are required') raise ValueError(_('policy, region and service are required'))
policy_id = base.getid(policy) policy_id = base.getid(policy)
region_id = base.getid(region) region_id = base.getid(region)
@@ -121,7 +122,7 @@ class EndpointPolicyManager(base.Manager):
""" """
if not endpoint: if not endpoint:
raise ValueError('endpoint is required') raise ValueError(_('endpoint is required'))
endpoint_id = base.getid(endpoint) endpoint_id = base.getid(endpoint)
url = ('/endpoints/%(endpoint_id)s/%(ext_name)s/policy') % { url = ('/endpoints/%(endpoint_id)s/%(ext_name)s/policy') % {
@@ -141,7 +142,7 @@ class EndpointPolicyManager(base.Manager):
""" """
if not policy: if not policy:
raise ValueError('policy is required') raise ValueError(_('policy is required'))
policy_id = base.getid(policy) policy_id = base.getid(policy)
url = ('/policies/%(policy_id)s/%(ext_name)s/endpoints') % { url = ('/policies/%(policy_id)s/%(ext_name)s/endpoints') % {

View File

@@ -11,6 +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 keystoneclient.i18n import _
from keystoneclient.v3.contrib.oauth1 import access_tokens from keystoneclient.v3.contrib.oauth1 import access_tokens
from keystoneclient.v3.contrib.oauth1 import consumers from keystoneclient.v3.contrib.oauth1 import consumers
from keystoneclient.v3.contrib.oauth1 import request_tokens from keystoneclient.v3.contrib.oauth1 import request_tokens
@@ -59,6 +60,6 @@ class OAuthManagerOptionalImportProxy(object):
def __getattribute__(self, name): def __getattribute__(self, name):
if name in ('access_tokens', 'consumers', 'request_tokens'): if name in ('access_tokens', 'consumers', 'request_tokens'):
raise NotImplementedError( raise NotImplementedError(
'To use %r oauthlib must be installed' % name) _('To use %r oauthlib must be installed') % name)
return super(OAuthManagerOptionalImportProxy, return super(OAuthManagerOptionalImportProxy,
self).__getattribute__(name) self).__getattribute__(name)

View File

@@ -14,6 +14,7 @@ from oslo.utils import timeutils
from keystoneclient import base from keystoneclient import base
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _
class Trust(base.Resource): class Trust(base.Resource):
@@ -75,8 +76,8 @@ class TrustManager(base.CrudManager):
**kwargs) **kwargs)
def update(self): def update(self):
raise exceptions.MethodNotImplemented('Update not supported' raise exceptions.MethodNotImplemented(
' for trusts') _('Update not supported for trusts'))
def list(self, trustee_user=None, trustor_user=None, **kwargs): def list(self, trustee_user=None, trustor_user=None, **kwargs):
"""List Trusts.""" """List Trusts."""

View File

@@ -15,6 +15,7 @@
# under the License. # under the License.
from keystoneclient import base from keystoneclient import base
from keystoneclient.i18n import _
from keystoneclient import utils from keystoneclient import utils
@@ -46,7 +47,7 @@ class CredentialManager(base.CrudManager):
return data return data
else: else:
raise ValueError( raise ValueError(
"Credential requires blob to be specified") _("Credential requires blob to be specified"))
@utils.positional(1, enforcement=utils.positional.WARN) @utils.positional(1, enforcement=utils.positional.WARN)
def create(self, user, type, blob=None, data=None, project=None, **kwargs): def create(self, user, type, blob=None, data=None, project=None, **kwargs):

View File

@@ -16,6 +16,7 @@
from keystoneclient import base from keystoneclient import base
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _
from keystoneclient import utils from keystoneclient import utils
@@ -45,7 +46,7 @@ class EndpointManager(base.CrudManager):
def _validate_interface(self, interface): def _validate_interface(self, interface):
if interface is not None and interface not in VALID_INTERFACES: if interface is not None and interface not in VALID_INTERFACES:
msg = '"interface" must be one of: %s' msg = _('"interface" must be one of: %s')
msg = msg % ', '.join(VALID_INTERFACES) msg = msg % ', '.join(VALID_INTERFACES)
raise exceptions.ValidationError(msg) raise exceptions.ValidationError(msg)

View File

@@ -12,6 +12,7 @@
from keystoneclient import base from keystoneclient import base
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _
class RoleAssignment(base.Resource): class RoleAssignment(base.Resource):
@@ -37,12 +38,12 @@ class RoleAssignmentManager(base.CrudManager):
def _check_not_user_and_group(self, user, group): def _check_not_user_and_group(self, user, group):
if user and group: if user and group:
msg = 'Specify either a user or group, not both' msg = _('Specify either a user or group, not both')
raise exceptions.ValidationError(msg) raise exceptions.ValidationError(msg)
def _check_not_domain_and_project(self, domain, project): def _check_not_domain_and_project(self, domain, project):
if domain and project: if domain and project:
msg = 'Specify either a domain or project, not both' msg = _('Specify either a domain or project, not both')
raise exceptions.ValidationError(msg) raise exceptions.ValidationError(msg)
def list(self, user=None, group=None, project=None, domain=None, role=None, def list(self, user=None, group=None, project=None, domain=None, role=None,
@@ -87,25 +88,25 @@ class RoleAssignmentManager(base.CrudManager):
return super(RoleAssignmentManager, self).list(**query_params) return super(RoleAssignmentManager, self).list(**query_params)
def create(self, **kwargs): def create(self, **kwargs):
raise exceptions.MethodNotImplemented('Create not supported for' raise exceptions.MethodNotImplemented(
' role assignments') _('Create not supported for role assignments'))
def update(self, **kwargs): def update(self, **kwargs):
raise exceptions.MethodNotImplemented('Update not supported for' raise exceptions.MethodNotImplemented(
' role assignments') _('Update not supported for role assignments'))
def get(self, **kwargs): def get(self, **kwargs):
raise exceptions.MethodNotImplemented('Get not supported for' raise exceptions.MethodNotImplemented(
' role assignments') _('Get not supported for role assignments'))
def find(self, **kwargs): def find(self, **kwargs):
raise exceptions.MethodNotImplemented('Find not supported for' raise exceptions.MethodNotImplemented(
' role assignments') _('Find not supported for role assignments'))
def put(self, **kwargs): def put(self, **kwargs):
raise exceptions.MethodNotImplemented('Put not supported for' raise exceptions.MethodNotImplemented(
' role assignments') _('Put not supported for role assignments'))
def delete(self, **kwargs): def delete(self, **kwargs):
raise exceptions.MethodNotImplemented('Delete not supported for' raise exceptions.MethodNotImplemented(
' role assignments') _('Delete not supported for role assignments'))

View File

@@ -16,6 +16,7 @@
from keystoneclient import base from keystoneclient import base
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.i18n import _
from keystoneclient import utils from keystoneclient import utils
@@ -59,18 +60,18 @@ class RoleManager(base.CrudManager):
def _require_domain_xor_project(self, domain, project): def _require_domain_xor_project(self, domain, project):
if domain and project: if domain and project:
msg = 'Specify either a domain or project, not both' msg = _('Specify either a domain or project, not both')
raise exceptions.ValidationError(msg) raise exceptions.ValidationError(msg)
elif not (domain or project): elif not (domain or project):
msg = 'Must specify either a domain or project' msg = _('Must specify either a domain or project')
raise exceptions.ValidationError(msg) raise exceptions.ValidationError(msg)
def _require_user_xor_group(self, user, group): def _require_user_xor_group(self, user, group):
if user and group: if user and group:
msg = 'Specify either a user or group, not both' msg = _('Specify either a user or group, not both')
raise exceptions.ValidationError(msg) raise exceptions.ValidationError(msg)
elif not (user or group): elif not (user or group):
msg = 'Must specify either a user or group' msg = _('Must specify either a user or group')
raise exceptions.ValidationError(msg) raise exceptions.ValidationError(msg)
@utils.positional(1, enforcement=utils.positional.WARN) @utils.positional(1, enforcement=utils.positional.WARN)

View File

@@ -18,6 +18,7 @@ import logging
from keystoneclient import base from keystoneclient 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__)
@@ -41,7 +42,7 @@ class UserManager(base.CrudManager):
def _require_user_and_group(self, user, group): def _require_user_and_group(self, user, group):
if not (user and group): if not (user and group):
msg = 'Specify both a user and a group' msg = _('Specify both a user and a group')
raise exceptions.ValidationError(msg) raise exceptions.ValidationError(msg)
@utils.positional(1, enforcement=utils.positional.WARN) @utils.positional(1, enforcement=utils.positional.WARN)
@@ -58,8 +59,8 @@ class UserManager(base.CrudManager):
will be used. will be used.
""" """
if project: if project:
LOG.warning("The project argument is deprecated, " LOG.warning(_LW("The project argument is deprecated, "
"use default_project instead.") "use default_project instead."))
default_project_id = base.getid(default_project) or base.getid(project) default_project_id = base.getid(default_project) or base.getid(project)
user_data = base.filter_none(name=name, user_data = base.filter_none(name=name,
domain_id=base.getid(domain), domain_id=base.getid(domain),
@@ -92,8 +93,8 @@ class UserManager(base.CrudManager):
will be used. will be used.
""" """
if project: if project:
LOG.warning("The project argument is deprecated, " LOG.warning(_LW("The project argument is deprecated, "
"use default_project instead.") "use default_project instead."))
default_project_id = base.getid(default_project) or base.getid(project) default_project_id = base.getid(default_project) or base.getid(project)
if group: if group:
base_url = '/groups/%s' % base.getid(group) base_url = '/groups/%s' % base.getid(group)
@@ -124,8 +125,8 @@ class UserManager(base.CrudManager):
will be used. will be used.
""" """
if project: if project:
LOG.warning("The project argument is deprecated, " LOG.warning(_LW("The project argument is deprecated, "
"use default_project instead.") "use default_project instead."))
default_project_id = base.getid(default_project) or base.getid(project) default_project_id = base.getid(default_project) or base.getid(project)
user_data = base.filter_none(name=name, user_data = base.filter_none(name=name,
domain_id=base.getid(domain), domain_id=base.getid(domain),
@@ -145,11 +146,11 @@ class UserManager(base.CrudManager):
def update_password(self, old_password, new_password): def update_password(self, old_password, new_password):
"""Update the password for the user the token belongs to.""" """Update the password for the user the token belongs to."""
if not (old_password and new_password): if not (old_password and new_password):
msg = 'Specify both the current password and a new password' msg = _('Specify both the current password and a new password')
raise exceptions.ValidationError(msg) raise exceptions.ValidationError(msg)
if old_password == new_password: if old_password == new_password:
msg = 'Old password and new password must be different.' msg = _('Old password and new password must be different.')
raise exceptions.ValidationError(msg) raise exceptions.ValidationError(msg)
params = {'user': {'password': new_password, params = {'user': {'password': new_password,

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