diff options
176 files changed, 33791 insertions, 5569 deletions
@@ -1,5 +1,6 @@ *.pyc *.swp +*.egg/ vendor .ksl-venv .venv @@ -13,7 +14,6 @@ cover/* covhtml pep8.txt nosetests.xml -*.db doc/build .DS_Store doc/source/modules.rst @@ -24,6 +24,6 @@ build/ dist/ etc/keystone.conf etc/logging.conf -tests/test.db.pristine +tests/tmp/ .project .pydevproject diff --git a/MANIFEST.in b/MANIFEST.in index 93b762f7..2373ea28 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -20,4 +20,4 @@ graft tests graft tools graft examples recursive-include keystone *.json *.xml *.cfg *.pem README *.po *.pot *.sql -global-exclude *.pyc *.sdx *.log *.db *.swp +global-exclude *.pyc *.sdx *.log *.db *.swp tests/tmp/* diff --git a/doc/source/_theme/layout.html b/doc/source/_theme/layout.html deleted file mode 100644 index 750b7822..00000000 --- a/doc/source/_theme/layout.html +++ /dev/null @@ -1,83 +0,0 @@ -{% extends "basic/layout.html" %} -{% set css_files = css_files + ['_static/tweaks.css'] %} -{% set script_files = script_files + ['_static/jquery.tweet.js'] %} - -{%- macro sidebar() %} - {%- if not embedded %}{% if not theme_nosidebar|tobool %} - <div class="sphinxsidebar"> - <div class="sphinxsidebarwrapper"> - {%- block sidebarlogo %} - {%- if logo %} - <p class="logo"><a href="{{ pathto(master_doc) }}"> - <img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/> - </a></p> - {%- endif %} - {%- endblock %} - {%- block sidebartoc %} - {%- if display_toc %} - <h3><a href="{{ pathto(master_doc) }}">{{ _('Table Of Contents') }}</a></h3> - {{ toc }} - {%- endif %} - {%- endblock %} - {%- block sidebarrel %} - {%- if prev %} - <h4>{{ _('Previous topic') }}</h4> - <p class="topless"><a href="{{ prev.link|e }}" - title="{{ _('previous chapter') }}">{{ prev.title }}</a></p> - {%- endif %} - {%- if next %} - <h4>{{ _('Next topic') }}</h4> - <p class="topless"><a href="{{ next.link|e }}" - title="{{ _('next chapter') }}">{{ next.title }}</a></p> - {%- endif %} - {%- endblock %} - {%- block sidebarsourcelink %} - {%- if show_source and has_source and sourcename %} - <h3>{{ _('This Page') }}</h3> - <ul class="this-page-menu"> - <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}" - rel="nofollow">{{ _('Show Source') }}</a></li> - </ul> - {%- endif %} - {%- endblock %} - {%- if customsidebar %} - {% include customsidebar %} - {%- endif %} - {%- block sidebarsearch %} - {%- if pagename != "search" %} - <div id="searchbox" style="display: none"> - <h3>{{ _('Quick search') }}</h3> - <form class="search" action="{{ pathto('search') }}" method="get"> - <input type="text" name="q" size="18" /> - <input type="submit" value="{{ _('Go') }}" /> - <input type="hidden" name="check_keywords" value="yes" /> - <input type="hidden" name="area" value="default" /> - </form> - <p class="searchtip" style="font-size: 90%"> - {{ _('Enter search terms or a module, class or function name.') }} - </p> - </div> - <script type="text/javascript">$('#searchbox').show(0);</script> - {%- endif %} - {%- endblock %} - </div> - </div> - {%- endif %}{% endif %} -{%- endmacro %} - -{% block relbar1 %}{% endblock relbar1 %} - -{% block header %} - <div id="header"> - <h1 id="logo"><a href="http://www.openstack.org/">OpenStack</a></h1> - <ul id="navigation"> - <li><a href="http://www.openstack.org/" title="Go to the Home page" class="link">Home</a></li> - <li><a href="http://www.openstack.org/projects/" title="Go to the OpenStack Projects page">Projects</a></li> - <li><a href="http://www.openstack.org/user-stories/" title="Go to the User Stories page" class="link">User Stories</a></li> - <li><a href="http://www.openstack.org/community/" title="Go to the Community page" class="link">Community</a></li> - <li><a href="http://www.openstack.org/blog/" title="Go to the OpenStack Blog">Blog</a></li> - <li><a href="http://wiki.openstack.org/" title="Go to the OpenStack Wiki">Wiki</a></li> - <li><a href="http://docs.openstack.org/" title="Go to OpenStack Documentation" class="current">Documentation</a></li> - </ul> - </div> -{% endblock %}
\ No newline at end of file diff --git a/doc/source/_theme/theme.conf b/doc/source/_theme/theme.conf deleted file mode 100644 index 1cc40044..00000000 --- a/doc/source/_theme/theme.conf +++ /dev/null @@ -1,4 +0,0 @@ -[theme] -inherit = basic -stylesheet = nature.css -pygments_style = tango diff --git a/doc/source/architecture.rst b/doc/source/architecture.rst index 7ffaea4b..c3ddf0ce 100644 --- a/doc/source/architecture.rst +++ b/doc/source/architecture.rst @@ -178,7 +178,7 @@ interpolation):: LDAP Backend ------------ -The LDAP backend stored Users and Tenents in separate Subtrees. Roles are recorded +The LDAP backend stored Users and Tenants in separate Subtrees. Roles are recorded as entries under the Tenants. diff --git a/doc/source/conf.py b/doc/source/conf.py index 293edf44..cd585d68 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -28,21 +28,19 @@ sys.path.insert(0, os.path.abspath('../..')) # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -#extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', -# 'sphinx.ext.todo', 'sphinx.ext.coverage'] extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', - # 'sphinx.ect.intersphinx', - 'sphinx.ext.coverage'] + 'sphinx.ext.coverage', + 'oslo.sphinx', + ] todo_include_todos = True # Add any paths that contain templates here, relative to this directory. -templates_path = [] -if os.getenv('HUDSON_PUBLISH_DOCS'): - templates_path = ['_ga', '_templates'] -else: - templates_path = ['_templates'] +# if os.getenv('HUDSON_PUBLISH_DOCS'): +# templates_path = ['_ga', '_templates'] +# else: +# templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' @@ -109,8 +107,8 @@ man_pages = [ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme_path = ["."] -html_theme = '_theme' +# html_theme_path = ["."] +# html_theme = '_theme' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst index 03fa1d63..1c339490 100644 --- a/doc/source/configuration.rst +++ b/doc/source/configuration.rst @@ -74,11 +74,12 @@ following sections: * ``[s3]`` - Amazon S3 authentication driver configuration. * ``[identity]`` - identity system driver configuration * ``[catalog]`` - service catalog driver configuration -* ``[token]`` - token driver configuration +* ``[token]`` - token driver & token provider configuration * ``[policy]`` - policy system driver configuration for RBAC * ``[signing]`` - cryptographic signatures for PKI based tokens * ``[ssl]`` - SSL configuration * ``[auth]`` - Authentication plugin configuration +* ``[os_inherit]`` - Inherited Role Assignment extension * ``[paste_deploy]`` - Pointer to the PasteDeploy configuration file The Keystone primary configuration file is expected to be named ``keystone.conf``. @@ -106,7 +107,10 @@ file. It is up to the plugin to register its own configuration options. * ``methods`` - comma-delimited list of authentication plugin names * ``<plugin name>`` - specify the class which handles to authentication method, in the same manner as one would specify a backend driver. -Keystone provides two authentication methods by default. ``password`` handles password authentication and ``token`` handles token authentication. +Keystone provides three authentication methods by default. ``password`` handles password +authentication and ``token`` handles token authentication. ``external`` is used in conjunction +with authentication performed by a container web server that sets the ``REMOTE_USER`` +environment variable. How to Implement an Authentication Plugin ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -148,6 +152,32 @@ invoked, all plugins must succeed in order to for the entire authentication to be successful. Furthermore, all the plugins invoked must agree on the ``user_id`` in the ``auth_context``. +The ``REMOTE_USER`` environment variable is only set from a containing webserver. However, +to ensure that a user must go through other authentication mechanisms, even if this variable +is set, remove ``external`` from the list of plugins specified in ``methods``. This effectively +disables external authentication. + + +Token Provider +-------------- + +Keystone supports customizable token provider and it is specified in the +``[token]`` section of the configuration file. Keystone provides both UUID and +PKI token providers, with PKI token provider enabled as default. However, users +may register their own token provider by configuring the following property. + +* ``provider`` - token provider driver. Defaults to + ``keystone.token.providers.pki.Provider`` + +Note that ``token_format`` in the ``[signing]`` section is deprecated but still +being supported for backward compatibility. Therefore, if ``provider`` is set +to ``keystone.token.providers.pki.Provider``, ``token_format`` must be ``PKI``. +Conversely, if ``provider`` is ``keystone.token.providers.uuid.Provider``, +``token_format`` must be ``UUID``. + +For a customized provider, ``token_format`` must not set to ``PKI`` or +``UUID``. + Certificates for PKI -------------------- @@ -163,7 +193,9 @@ private key should only be readable by the system user that will run Keystone. The values that specify where to read the certificates are under the ``[signing]`` section of the configuration file. The configuration values are: -* ``token_format`` - Determines the algorithm used to generate tokens. Can be either ``UUID`` or ``PKI``. Defaults to ``PKI`` +* ``token_format`` - Determines the algorithm used to generate tokens. Can be + either ``UUID`` or ``PKI``. Defaults to ``PKI``. This option must be used in + conjunction with ``provider`` configuration in the ``[token]`` section. * ``certfile`` - Location of certificate used to verify tokens. Default is ``/etc/keystone/ssl/certs/signing_cert.pem`` * ``keyfile`` - Location of private key used to sign tokens. Default is ``/etc/keystone/ssl/private/signing_key.pem`` * ``ca_certs`` - Location of certificate for the authority that issued the above certificate. Default is ``/etc/keystone/ssl/certs/ca.pem`` @@ -460,7 +492,56 @@ Each user can then change their own password with a HTTP PATCH :: -H "X_Auth_Token: <authtokenid>" -d '{"user": {"password": "ABCD", "original_password": "DCBA"}}' In addition to changing their password all of the users current tokens will be -deleted (if the backend used is kvs or sql) +deleted (if the backend used is sql) + + +Inherited Role Assignment Extension +----------------------------------- + +Keystone provides an optional extension that adds the capability to assign roles to a domain that, rather than +affect the domain itself, are instead inherited to all projects owned by theat domain. This extension is disabled by +default, but can be enabled by including the following in ``keystone.conf``. + + [os_inherit] + enabled = True + + +Token Binding +------------- + +Token binding refers to the practice of embedding information from external +authentication providers (like a company's Kerberos server) inside the token +such that a client may enforce that the token only be used in conjunction with +that specified authentication. This is an additional security mechanism as it +means that if a token is stolen it will not be usable without also providing the +external authentication. + +To activate token binding you must specify the types of authentication that +token binding should be used for in ``keystone.conf`` e.g.:: + + [token] + bind = kerberos + +Currently only ``kerberos`` is supported. + +To enforce checking of token binding the ``enforce_token_bind`` parameter +should be set to one of the following modes: + +* ``disabled`` disable token bind checking +* ``permissive`` enable bind checking, if a token is bound to a mechanism that + is unknown to the server then ignore it. This is the default. +* ``strict`` enable bind checking, if a token is bound to a mechanism that is + unknown to the server then this token should be rejected. +* ``required`` enable bind checking and require that at least 1 bind mechanism + is used for tokens. +* named enable bind checking and require that the specified authentication + mechanism is used. e.g.:: + + [token] + enforce_token_bind = kerberos + + *Do not* set ``enforce_token_bind = named`` as there is not an authentication + mechanism called ``named``. Sample Configuration Files @@ -1079,7 +1160,7 @@ if the backend is providing too much output, in such case the configuration will look like:: [ldap] - user_filter = (memberof=CN=openstack-users,OU=workgroups,DC=openstack,DC=com) + user_filter = (memberof=CN=openstack-users,OU=workgroups,DC=openstack,DC=org) tenant_filter = role_filter = diff --git a/doc/source/configuringservices.rst b/doc/source/configuringservices.rst index 8ea7ad90..645ab5da 100644 --- a/doc/source/configuringservices.rst +++ b/doc/source/configuringservices.rst @@ -93,7 +93,7 @@ Create a tenant for the services, typically named 'service' (however, the name c This returns a UUID of the tenant - keep that, you'll need it when creating the users and specifying the roles. -Create service users for nova, glance, swift, and quantum (or whatever +Create service users for nova, glance, swift, and neutron (or whatever subset is relevant to your deployment):: keystone user-create --name=nova \ diff --git a/doc/source/man/keystone-all.rst b/doc/source/man/keystone-all.rst index 9b0859d9..76d5ab1f 100644 --- a/doc/source/man/keystone-all.rst +++ b/doc/source/man/keystone-all.rst @@ -6,7 +6,7 @@ keystone-all Keystone Startup Command ------------------------ -:Author: openstack@lists.launchpad.net +:Author: openstack@lists.openstack.org :Date: 2010-11-16 :Copyright: OpenStack LLC :Version: 2012.1 diff --git a/doc/source/man/keystone-manage.rst b/doc/source/man/keystone-manage.rst index 84a3ec9f..1da4b40a 100644 --- a/doc/source/man/keystone-manage.rst +++ b/doc/source/man/keystone-manage.rst @@ -6,7 +6,7 @@ keystone-manage Keystone Management Utility --------------------------- -:Author: openstack@lists.launchpad.net +:Author: openstack@lists.openstack.org :Date: 2010-11-16 :Copyright: OpenStack LLC :Version: 2012.1 diff --git a/etc/keystone.conf.sample b/etc/keystone.conf.sample index 9a36316d..a49a9a5e 100644 --- a/etc/keystone.conf.sample +++ b/etc/keystone.conf.sample @@ -109,6 +109,11 @@ # delegation and impersonation features can be optionally disabled # enabled = True +[os_inherit] +# role-assignment inheritance to projects from owning domain can be +# optionally enabled +# enabled = False + [catalog] # dynamic, sql-based backend (supports API/CLI-based management commands) # driver = keystone.catalog.backends.sql.Catalog @@ -119,23 +124,40 @@ # template_file = default_catalog.templates [token] +# Provides token persistence. # driver = keystone.token.backends.sql.Token +# Controls the token construction, validation, and revocation operations. +# Core providers are keystone.token.providers.[pki|uuid].Provider +# provider = + # Amount of time a token should remain valid (in seconds) # expiration = 86400 +# External auth mechanisms that should add bind information to token. +# eg kerberos, x509 +# bind = + +# Enforcement policy on tokens presented to keystone with bind information. +# One of disabled, permissive, strict, required or a specifically required bind +# mode e.g. kerberos or x509 to require binding to that authentication. +# enforce_token_bind = permissive + [policy] # driver = keystone.policy.backends.sql.Policy [ec2] # driver = keystone.contrib.ec2.backends.kvs.Ec2 +[assignment] +# driver = + [ssl] #enable = True -#certfile = /etc/keystone/ssl/certs/keystone.pem -#keyfile = /etc/keystone/ssl/private/keystonekey.pem -#ca_certs = /etc/keystone/ssl/certs/ca.pem -#ca_key = /etc/keystone/ssl/certs/cakey.pem +#certfile = /etc/keystone/pki/certs/ssl_cert.pem +#keyfile = /etc/keystone/pki/private/ssl_key.pem +#ca_certs = /etc/keystone/pki/certs/cacert.pem +#ca_key = /etc/keystone/pki/private/cakey.pem #key_size = 1024 #valid_days = 3650 #ca_password = None @@ -143,11 +165,14 @@ #cert_subject = /C=US/ST=Unset/L=Unset/O=Unset/CN=localhost [signing] -#token_format = PKI -#certfile = /etc/keystone/ssl/certs/signing_cert.pem -#keyfile = /etc/keystone/ssl/private/signing_key.pem -#ca_certs = /etc/keystone/ssl/certs/ca.pem -#ca_key = /etc/keystone/ssl/certs/cakey.pem +# Deprecated in favor of provider in the [token] section +# Allowed values are PKI or UUID +#token_format = + +#certfile = /etc/keystone/pki/certs/signing_cert.pem +#keyfile = /etc/keystone/pki/private/signing_key.pem +#ca_certs = /etc/keystone/pki/certs/cacert.pem +#ca_key = /etc/keystone/pki/private/cakey.pem #key_size = 2048 #valid_days = 3650 #ca_password = None @@ -253,7 +278,8 @@ # user_additional_attribute_mapping = [auth] -methods = password,token +methods = external,password,token +#external = keystone.auth.plugins.external.ExternalDefault password = keystone.auth.plugins.password.Password token = keystone.auth.plugins.token.Token diff --git a/etc/policy.json b/etc/policy.json index 4aad4e8c..2c82f994 100644 --- a/etc/policy.json +++ b/etc/policy.json @@ -66,6 +66,8 @@ "identity:create_grant": [["rule:admin_required"]], "identity:revoke_grant": [["rule:admin_required"]], + "identity:list_role_assignments": [["rule:admin_required"]], + "identity:get_policy": [["rule:admin_required"]], "identity:list_policies": [["rule:admin_required"]], "identity:create_policy": [["rule:admin_required"]], diff --git a/examples/pki/certs/cacert.pem b/examples/pki/certs/cacert.pem index a0d98c6e..2f31d126 100644 --- a/examples/pki/certs/cacert.pem +++ b/examples/pki/certs/cacert.pem @@ -1,18 +1,23 @@ -----BEGIN CERTIFICATE----- -MIIC0TCCAjqgAwIBAgIJANsHKV73HYOwMA0GCSqGSIb3DQEBBQUAMIGeMQowCAYD +MIID1jCCAr6gAwIBAgIJAKiIU3dYUGKeMA0GCSqGSIb3DQEBBQUAMIGeMQowCAYD VQQFEwE1MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVN1bm55 dmFsZTESMBAGA1UEChMJT3BlblN0YWNrMREwDwYDVQQLEwhLZXlzdG9uZTElMCMG CSqGSIb3DQEJARYWa2V5c3RvbmVAb3BlbnN0YWNrLm9yZzEUMBIGA1UEAxMLU2Vs -ZiBTaWduZWQwIBcNMTIxMTA1MTgxODI0WhgPMjA3MTA0MzAxODE4MjRaMIGeMQow +ZiBTaWduZWQwIBcNMTMwNzA5MTYyNTAwWhgPMjA3MjAxMDExNjI1MDBaMIGeMQow CAYDVQQFEwE1MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVN1 bm55dmFsZTESMBAGA1UEChMJT3BlblN0YWNrMREwDwYDVQQLEwhLZXlzdG9uZTEl MCMGCSqGSIb3DQEJARYWa2V5c3RvbmVAb3BlbnN0YWNrLm9yZzEUMBIGA1UEAxML -U2VsZiBTaWduZWQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALzI17ExCaqd -r7xY2Q5CBZ1bW1lsrXxS8eNJRdQtskDuQVAluY03/OGZd8HQYiiY/ci2tYy7BNIC -bh5GaO95eqTDykJR3liOYE/tHbY6puQlj2ZivmhlSd2d5d7lF0/H28RQsLu9VktM -uw6q9DpDm35jfrr8LgSeA3MdVqcS/4OhAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMB -Af8wDQYJKoZIhvcNAQEFBQADgYEAjSQND7i1dNZtLKpWgX+JqMr3BdVlM15mFeVr -C26ZspZjZVY5okdozO9gU3xcwRe4Cg30sKFOe6EBQKpkTZucFOXwBtD3h6dWJrdD -c+m/CL/rs0GatDavbaIT2vv405SQUQooCdVh72LYel+4/a6xmRd7fQx3iEXN9QYj -vmHJUcA= +U2VsZiBTaWduZWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCh1U+N +3g2cjFi7GeVf21FIv8MDhughFCey9rysAuqFONSFYo2rectLgpDtVy4BFFUFlxmh +8Ci9TEZ5LiA31tbc4584GxvlLt4dg8aFsUJRBKq0L9i7W5v9uFpHrY1Zr+P4vwG+ +v7IWOuzw19f517eGpp6LLcj2vrpN9Yb63rrydKOqr0KJodMd+vFKmi+euFcPqs6s +w1OiC5DpJN479CGl2Fs1WzMoKDedRNiXG7ysrVrYQIkfMBABBPIwilq1xXZz9Ybo +0PbNgOu6xpSsy9hq+IzxcwYsr5CwIcbqW6Ju+Ti2iBEaff20lW7dFzO4kwrcqOr9 +Jnn7qE8YfJo9Hyj3AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN +AQEFBQADggEBAGWFTQTe2FwvwGWa/Bx3Ypc8pJ05ucmGDm8XZiUHj1mOvFHTcveL +Iofb+vR2lynr+MwF9Dn1szGteVNn/QxrHJIoxsgf1n/9fdyYqjoKWXblNBMt5jhr +IlMGdQMqHSDzlkZKbcXg5vzHnG5mrwh0rojcZItZznXTSo/XnujEtHwIvCo6rk9c +tRRzpkcDkg+/SZf2izchsLoEQVsJsIZMnWl0hUGFHaDfx2JQn7bnAcC84wPVhRJ+ +Xa3kDok1r7Nd7Vr/Wf0hCNRxyv2dySD/bq5iCEl1HNik3KCq4eUicTtkGe5N+Was +ucf1RhPD3oZbxlTX4QDN7grSCdrTESyuhfc= -----END CERTIFICATE----- diff --git a/examples/pki/certs/middleware.pem b/examples/pki/certs/middleware.pem index 86095248..6546753e 100644 --- a/examples/pki/certs/middleware.pem +++ b/examples/pki/certs/middleware.pem @@ -1,33 +1,50 @@ -----BEGIN CERTIFICATE----- -MIICoTCCAgoCARAwDQYJKoZIhvcNAQEFBQAwgZ4xCjAIBgNVBAUTATUxCzAJBgNV +MIIDpjCCAo4CARAwDQYJKoZIhvcNAQEFBQAwgZ4xCjAIBgNVBAUTATUxCzAJBgNV BAYTAlVTMQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQK EwlPcGVuU3RhY2sxETAPBgNVBAsTCEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZr ZXlzdG9uZUBvcGVuc3RhY2sub3JnMRQwEgYDVQQDEwtTZWxmIFNpZ25lZDAgFw0x -MjExMDUxODE4MjRaGA8yMDcxMDQzMDE4MTgyNFowgZAxCzAJBgNVBAYTAlVTMQsw +MzA3MDkxNjI1MDBaGA8yMDcyMDEwMTE2MjUwMFowgZAxCzAJBgNVBAYTAlVTMQsw CQYDVQQIEwJDQTESMBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQKEwlPcGVuU3Rh Y2sxETAPBgNVBAsTCEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZrZXlzdG9uZUBv -cGVuc3RhY2sub3JnMRIwEAYDVQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEB -BQADgY0AMIGJAoGBANRG3ZkIJ+NaY9smirkZ+Lzf1Ka18xOvc2kizemUMeAchs9h -lP0Kpm8EBHal1vgzSuXncP8gyQ6nMZUw5NhFMZ1kLSfzoB/hCyTlIp/4VZbCAtn4 -3zlTUSgQQMH+6I4k4sZDOiIAE7yvzEMa71RkqBzduuFoeuhBm5oqmRa8kac5AgMB -AAEwDQYJKoZIhvcNAQEFBQADgYEAJLnmyYiBDNdykLeh3+HXCOExUt49/OzomB6c -6NWq3j7efYBfh6zCgyowx/v0hEVcxYBunTfXgOGunjx0u5X13PuLRO7Qxv6Crdy6 -st0mZ0itCsp58uGz5n+ZVhG//NiweTKw9M12Mejs0L/JGtf5gPBCFkVvrl8ffwRG -060Ep/k= +cGVuc3RhY2sub3JnMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC5dpW18l3bs+Mcj/JdhaAa+qw1RJwShm06g+q38ZoC +cCmRO3/XyHghgHWdVa+FKVm2ug923dE2PW4GSI1pZa3iqbT9Yj70nxN+0l94iym+ +v9/P7irolvo5OWBbBIJT1Ubjps5fJ//gz6BdmwS0FuOy2qfKPnPhyBDH2VawtOgY +MLk+PSG3YQh7vM2YvDALPTPz/f4qPmhQpb69KBJQElFXPQ9Nu0ABCPWWC2tN87L5 +pakFw5zq46pttSJ7Izc8MXh3KQrh9FvjmiQuRnkMvQ/g887Sp6nEJ22ABPEFhuRr +89aup6wRD2CkA/8L3zSB5BV7tTK4hQiq07cTnV9Dv6bfAgMBAAEwDQYJKoZIhvcN +AQEFBQADggEBAIVz3ZwxSUF/y5ABmjnVIQaVVxH97bu07smFQUe0AB2I9R4xnBJ9 +jn93DpeixZvArCZuDuJEJvNER8S6L3r/OPMPrVzayxibXATaZRE8khMWEJpsnyeW +8paA5NuZJwN2NjlPOmT47J1m7ZjLgkrVwjhwQZPMnh5kG9690TBJNhg9x3Z8f6p3 +iKj2AfZWGhp9Xr2xOZCpfvAZmyvKOMeuHVrRZ2VWGuzojQd7fjSEDw/+Tg8Gw1LV +BQXjXiKQHsD1YID2a9Pe9yrBjO00ZMxMw8+wN9qrh+8vxfmwTO8tEkmcpvM4ivO3 +/oGGhQh6nSncERVI7rx+wBDnIHKBz6MU2Ow= -----END CERTIFICATE----- -----BEGIN PRIVATE KEY----- -MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANRG3ZkIJ+NaY9sm -irkZ+Lzf1Ka18xOvc2kizemUMeAchs9hlP0Kpm8EBHal1vgzSuXncP8gyQ6nMZUw -5NhFMZ1kLSfzoB/hCyTlIp/4VZbCAtn43zlTUSgQQMH+6I4k4sZDOiIAE7yvzEMa -71RkqBzduuFoeuhBm5oqmRa8kac5AgMBAAECgYBngOI94tcoKQO1cJaFaJ964Jyc -aO1L9OmOIvVJ5gNnpiEpbwgpVY8PZGMUwwoNXV0wumfDTmYaafVoLD35IcvtcS3D -Tmsm+zC3ZQYzbQrIkQrtXE+y4bMwtscOTd61YDFQE++0omg3qckVu8IYSdFtTb9D -SjSsWMnYoDmGrBqCHQJBAP2jq2I5fMPSR3LY5FdejwhyUcqs6AKyJD0BDJzIhdV6 -d0InWWss/atR4sMnOX7WKIo1m4+X+0+T2F69kj9hge8CQQDWQKTvbvlDugiziwNc -FRl+yC7YTJ34toRFI4xbszKL3vgk4KDgfSQeoPp9KeHXmjgTfXIOwSVI83QBoL1d -LHFXAkEAglD9VVJEEDiSDSfy6hDjXGugKon8CqaMh+tqF4PPf4eUjqC5CJ/tFYDV -CX+1wr01xw0UCAsGTDSiDstHwNjQcQJAAkF3+xVeBnqE8O77wBJwzEbrR1e3KhEx -31B6f9SpKZPVZP4Ac5ydrrzfJkY0nIKBKKNfegxKijQV+pZop/x5zQJASGTmKcW2 -WKj4P8PiolVlWH2ZTARSschff5wDV6nBneb5zWNgpPORrSRPl9yrYrgqk4vvjLh5 -rUiR/G65ZjmbnA== +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5dpW18l3bs+Mc +j/JdhaAa+qw1RJwShm06g+q38ZoCcCmRO3/XyHghgHWdVa+FKVm2ug923dE2PW4G +SI1pZa3iqbT9Yj70nxN+0l94iym+v9/P7irolvo5OWBbBIJT1Ubjps5fJ//gz6Bd +mwS0FuOy2qfKPnPhyBDH2VawtOgYMLk+PSG3YQh7vM2YvDALPTPz/f4qPmhQpb69 +KBJQElFXPQ9Nu0ABCPWWC2tN87L5pakFw5zq46pttSJ7Izc8MXh3KQrh9FvjmiQu +RnkMvQ/g887Sp6nEJ22ABPEFhuRr89aup6wRD2CkA/8L3zSB5BV7tTK4hQiq07cT +nV9Dv6bfAgMBAAECggEBAIB1K5L/kZUITulMptGyKUgmkjq/D98g7u0Vy/CmTkcc +Cx6F+LGsL9D8mfplDBKOpo4S530sfKk1+Uwu2ovDGqKhazQJ5ZMnz6gK7Ieg1ERD +wDDURTIeyKf0HtJMGD0av2QU+GIeYXQEO446PhLCu+n42zkQ8tDS8xSJbCsu0odV +ok6+i7nEg9sP4uDfAAtM8CUJbRpFTha+m2a7pOz3ylU7/ZV4FDIgJ+FEynaphXAo +bZE4MX5I7A4DDBp7/9g9HsgefByY4xiABuk7Rsyztyf2TrJEtcsVhiV4sCIIHsow +u60KGEcTQWj4npBIMgW1QUdrwmAAh/35gOjt9ZndgTkCgYEA2yT5DmihjVaNF65B +8VtdFcpESr8rr6FBmJ7z31m7MufeV1Inc5GqCK9agRmpr5sTYcgFB9it2IhW2WsA +xHv+7J04bd9DBtgTv58GWrISsCR/abMZnJrm+F5Rafk77jwjCx/SwFj79ybI83Ia +VJYMd7jqkxc00+DZT/3QWZqRrlsCgYEA2KeBBqUVdCpwNiJpgFM18HWjJx36HRk7 +YoFapXot/6R6A/rYmS+/goBZt2CWqqGtnXqWEZvH+v4L+WlUmYQrWwtoxpdR1oXz +EmlCxN7D9MbRVR7QVW24h5zdwPOlbCTGoKzowOs8UEjMfQ81zoMinLmcJgHQSyzs +OawgSF+DmM0CgYBQz26EELNaMktvKxQoE3/c9CyAv8Q1TKqqxBq8BxPP7s7/tkzU +AigIcdlW+Aapue7IxQCN5yocShJ0tE+hJPRZfpR7d7P4xx9pLxQhx766c4sEiEXu +iPSZK/artHuUG1r01DRcN7QabJP3qeDpxjcswuTFfu49H5IjPD5jfGsyNwKBgFjh +bvdQ5lo/xsUOnQV+HZTGTeaQT7l8TnZ85rkYRKKp0TysvgsqIYDiMuwd/fGGXnlK +fyI+LG51pmftpD1OkZLKPXOrRHGjhjK5aCDn2rAimGI5P/KsDpXj7r1ntyeEdtAX +32y1lIrDMtDjWomcFqkBJGQbPl540Xhfeub1+EDJAoGAUZGPT2itKnxEFsa1SKHW +yLeEsag/a9imAVyizo1WJn2WJaUhi1aHK49w6JRowIAzXXb7zLQt7BL8v+ydPVw3 +eySpXGqFuN/Prm3So0SeWllWcPsKFAzjgE0CWjNuB0GlAZGOaJOcWUNoOZjX/SDC +FpolIoaSad28tGc8tbEk3fU= -----END PRIVATE KEY----- diff --git a/examples/pki/certs/signing_cert.pem b/examples/pki/certs/signing_cert.pem index a6656490..3129e508 100644 --- a/examples/pki/certs/signing_cert.pem +++ b/examples/pki/certs/signing_cert.pem @@ -1,17 +1,22 @@ -----BEGIN CERTIFICATE----- -MIICoDCCAgkCAREwDQYJKoZIhvcNAQEFBQAwgZ4xCjAIBgNVBAUTATUxCzAJBgNV +MIIDpTCCAo0CAREwDQYJKoZIhvcNAQEFBQAwgZ4xCjAIBgNVBAUTATUxCzAJBgNV BAYTAlVTMQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQK EwlPcGVuU3RhY2sxETAPBgNVBAsTCEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZr ZXlzdG9uZUBvcGVuc3RhY2sub3JnMRQwEgYDVQQDEwtTZWxmIFNpZ25lZDAgFw0x -MjExMDUxODE4MjRaGA8yMDcxMDQzMDE4MTgyNFowgY8xCzAJBgNVBAYTAlVTMQsw +MzA3MDkxNjI1MDBaGA8yMDcyMDEwMTE2MjUwMFowgY8xCzAJBgNVBAYTAlVTMQsw CQYDVQQIEwJDQTESMBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQKEwlPcGVuU3Rh Y2sxETAPBgNVBAsTCEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZrZXlzdG9uZUBv -cGVuc3RhY2sub3JnMREwDwYDVQQDEwhLZXlzdG9uZTCBnzANBgkqhkiG9w0BAQEF -AAOBjQAwgYkCgYEA0GemENJ+fs5OaT8k4uA7ETRDA/oX/tUKCVAfxfYveHAdQqEK -DcUbthdXTnhkBnv0OZIpxBPxwREZSZK2I/hekPrBILZ4USzozFCgudXA43QMkBlc -uQ+VOI2/q5H4z2knxaexsBjPeIX7D9NowtTYFlOgSqCix8xWIcNW1x1En1cCAwEA -ATANBgkqhkiG9w0BAQUFAAOBgQA/EpklfmPBW7rEoxvocRDk63gDvQ1HxhQItQDF -9ALWdSwLtL8c3/TQzGgoKZ8+a+p7RnNEsmzNOWHTaWHL91GcRrAEhXwBtu4G/dLu -sXguhHj9UfT+6ivFbvDF2JK9rPpKhSqTVWVnkY5JQKinDX1wFRHLQB/SVHysT+zt -nkZ7wg== +cGVuc3RhY2sub3JnMREwDwYDVQQDEwhLZXlzdG9uZTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAMTC6IdNd9Cg1DshcrT5gRVRF36nEmjSA9QWdik7B925 +PK70U4F6j4pz/5JL7plIo/8rJ4jJz9ccE7m0iA+IuABtEhEwXkG9rj47Oy0J4ZyD +GSh2K1Bl78PA9zxXSzysUTSjBKdAh29dPYbJY7cgZJ0uC3AtfVceYiAOIi14SdFe +Z0LZLDXBuLaqUmSMrmKwJ9wAMOCb/jbBP9/3Ycd0GYjlvrSBU4Bqb8/NHasyO4Dp +PN68OAoyD5r5jUtV8QZN03UjIsoux8e0lrL6+MVtJo0OfWvlSrlzS5HKSryY+uqq +QEuxtZKpJM2MV85ujvjc8eDSChh2shhDjBem3FIlHKUCAwEAATANBgkqhkiG9w0B +AQUFAAOCAQEAed9fHgdJrk+gZcO5gsqq6uURfDOuYD66GsSdZw4BqHjYAcnyWq2d +a+iw7Uxkqu7iLf2k4+Hu3xjDFrce479OwZkSnbXmqB7XspTGOuM8MgT7jB/ypKTO +Z6qaZKSWK1Hta995hMrVVlhUNBLh0MPGqoVWYA4d7mblujgH9vp+4mpCciJagHks +8K5FBmI+pobB+uFdSYDoRzX9LTpStspK4e3IoY8baILuGcdKimRNBv6ItG4hMrnt +Ae1/nWMJyUu5rDTGf2V/vAaS0S/faJBwQSz1o38QHMTWHNspfwIdX3yMqI9u7/vY +lz3rLy5WdBdUgZrZ3/VLmJTiJVZu5Owq4Q== -----END CERTIFICATE----- diff --git a/examples/pki/certs/ssl_cert.pem b/examples/pki/certs/ssl_cert.pem index 4a415ebc..0b0877eb 100644 --- a/examples/pki/certs/ssl_cert.pem +++ b/examples/pki/certs/ssl_cert.pem @@ -1,17 +1,22 @@ -----BEGIN CERTIFICATE----- -MIICoTCCAgoCARAwDQYJKoZIhvcNAQEFBQAwgZ4xCjAIBgNVBAUTATUxCzAJBgNV +MIIDpjCCAo4CARAwDQYJKoZIhvcNAQEFBQAwgZ4xCjAIBgNVBAUTATUxCzAJBgNV BAYTAlVTMQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQK EwlPcGVuU3RhY2sxETAPBgNVBAsTCEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZr ZXlzdG9uZUBvcGVuc3RhY2sub3JnMRQwEgYDVQQDEwtTZWxmIFNpZ25lZDAgFw0x -MjExMDUxODE4MjRaGA8yMDcxMDQzMDE4MTgyNFowgZAxCzAJBgNVBAYTAlVTMQsw +MzA3MDkxNjI1MDBaGA8yMDcyMDEwMTE2MjUwMFowgZAxCzAJBgNVBAYTAlVTMQsw CQYDVQQIEwJDQTESMBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQKEwlPcGVuU3Rh Y2sxETAPBgNVBAsTCEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZrZXlzdG9uZUBv -cGVuc3RhY2sub3JnMRIwEAYDVQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEB -BQADgY0AMIGJAoGBANRG3ZkIJ+NaY9smirkZ+Lzf1Ka18xOvc2kizemUMeAchs9h -lP0Kpm8EBHal1vgzSuXncP8gyQ6nMZUw5NhFMZ1kLSfzoB/hCyTlIp/4VZbCAtn4 -3zlTUSgQQMH+6I4k4sZDOiIAE7yvzEMa71RkqBzduuFoeuhBm5oqmRa8kac5AgMB -AAEwDQYJKoZIhvcNAQEFBQADgYEAJLnmyYiBDNdykLeh3+HXCOExUt49/OzomB6c -6NWq3j7efYBfh6zCgyowx/v0hEVcxYBunTfXgOGunjx0u5X13PuLRO7Qxv6Crdy6 -st0mZ0itCsp58uGz5n+ZVhG//NiweTKw9M12Mejs0L/JGtf5gPBCFkVvrl8ffwRG -060Ep/k= +cGVuc3RhY2sub3JnMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC5dpW18l3bs+Mcj/JdhaAa+qw1RJwShm06g+q38ZoC +cCmRO3/XyHghgHWdVa+FKVm2ug923dE2PW4GSI1pZa3iqbT9Yj70nxN+0l94iym+ +v9/P7irolvo5OWBbBIJT1Ubjps5fJ//gz6BdmwS0FuOy2qfKPnPhyBDH2VawtOgY +MLk+PSG3YQh7vM2YvDALPTPz/f4qPmhQpb69KBJQElFXPQ9Nu0ABCPWWC2tN87L5 +pakFw5zq46pttSJ7Izc8MXh3KQrh9FvjmiQuRnkMvQ/g887Sp6nEJ22ABPEFhuRr +89aup6wRD2CkA/8L3zSB5BV7tTK4hQiq07cTnV9Dv6bfAgMBAAEwDQYJKoZIhvcN +AQEFBQADggEBAIVz3ZwxSUF/y5ABmjnVIQaVVxH97bu07smFQUe0AB2I9R4xnBJ9 +jn93DpeixZvArCZuDuJEJvNER8S6L3r/OPMPrVzayxibXATaZRE8khMWEJpsnyeW +8paA5NuZJwN2NjlPOmT47J1m7ZjLgkrVwjhwQZPMnh5kG9690TBJNhg9x3Z8f6p3 +iKj2AfZWGhp9Xr2xOZCpfvAZmyvKOMeuHVrRZ2VWGuzojQd7fjSEDw/+Tg8Gw1LV +BQXjXiKQHsD1YID2a9Pe9yrBjO00ZMxMw8+wN9qrh+8vxfmwTO8tEkmcpvM4ivO3 +/oGGhQh6nSncERVI7rx+wBDnIHKBz6MU2Ow= -----END CERTIFICATE----- diff --git a/examples/pki/cms/auth_token_revoked.pem b/examples/pki/cms/auth_token_revoked.pem index 842ff9bc..1435c1e9 100644 --- a/examples/pki/cms/auth_token_revoked.pem +++ b/examples/pki/cms/auth_token_revoked.pem @@ -1,5 +1,5 @@ -----BEGIN CMS----- -MIIHVgYJKoZIhvcNAQcCoIIHRzCCB0MCAQExCTAHBgUrDgMCGjCCBeQGCSqGSIb3 +MIIH1wYJKoZIhvcNAQcCoIIHyDCCB8QCAQExCTAHBgUrDgMCGjCCBeQGCSqGSIb3 DQEHAaCCBdUEggXReyJhY2Nlc3MiOiB7InNlcnZpY2VDYXRhbG9nIjogW3siZW5k cG9pbnRzIjogW3siYWRtaW5VUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo4Nzc2L3Yx LzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdhIiwgInJlZ2lvbiI6ICJy @@ -31,12 +31,14 @@ ImlkIjogInRlbmFudF9pZDEifX0sICJ1c2VyIjogeyJ1c2VybmFtZSI6ICJyZXZv a2VkX3VzZXJuYW1lMSIsICJyb2xlc19saW5rcyI6IFsicm9sZTEiLCJyb2xlMiJd LCAiaWQiOiAicmV2b2tlZF91c2VyX2lkMSIsICJyb2xlcyI6IFt7Im5hbWUiOiAi cm9sZTEifSwgeyJuYW1lIjogInJvbGUyIn1dLCAibmFtZSI6ICJyZXZva2VkX3Vz -ZXJuYW1lMSJ9fX0NCjGCAUkwggFFAgEBMIGkMIGeMQowCAYDVQQFEwE1MQswCQYD +ZXJuYW1lMSJ9fX0NCjGCAcowggHGAgEBMIGkMIGeMQowCAYDVQQFEwE1MQswCQYD VQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVN1bm55dmFsZTESMBAGA1UE ChMJT3BlblN0YWNrMREwDwYDVQQLEwhLZXlzdG9uZTElMCMGCSqGSIb3DQEJARYW a2V5c3RvbmVAb3BlbnN0YWNrLm9yZzEUMBIGA1UEAxMLU2VsZiBTaWduZWQCAREw -BwYFKw4DAhowDQYJKoZIhvcNAQEBBQAEgYDMKg2xebd6Ua2gxnNZBIHtDsRmfsGK -tfD8k03XWWDnjrKqKtYC1BKFJAhYCGgVH8a+jhM4ye8BjUZ7F42AYdnI2CrdvDGX -ULTe3iAW4WFrhvWB8KP2lllitY3fpbj+GyDwLqcMFALlWzYVioCzN00+MeCG8pUB -vdK6NKiV9sCZjg== +BwYFKw4DAhowDQYJKoZIhvcNAQEBBQAEggEAXY8JvllpyctcNlJByPLxhgLyRfFo +Ew+8Yq3O4FxOyfVkINvOz4EHTipY0M/K8OLwfxpRt7o/iGLGRDBTI6Dd+erXsus8 +NecnNxcWN9RUE2CZhoGj/0nhnNEGF+9Mlv3tMBngwoUJg2paSw/Vn2Q7RaqbOC05 +aZOSDoSX7Zf0DIS/T0ZPnmOUb9+N25M20ctMHksPMEq0qyf2oove0O+WMa/cA8JT +c2EAhew4WSD0Zv0GOAP30GS+hkNfA1GZTrvCQrpRs9jXhK4dR2bBsnUFVix1BEZ0 +sDhI8cXLvm16IpOO8ov6002ZoZhPn6Qo+0J8QOfdnjiwNnxLOEbuOIwPeQ== -----END CMS----- diff --git a/examples/pki/cms/auth_token_scoped.pem b/examples/pki/cms/auth_token_scoped.pem index cc0da169..5c02c954 100644 --- a/examples/pki/cms/auth_token_scoped.pem +++ b/examples/pki/cms/auth_token_scoped.pem @@ -1,5 +1,5 @@ -----BEGIN CMS----- -MIIHQAYJKoZIhvcNAQcCoIIHMTCCBy0CAQExCTAHBgUrDgMCGjCCBc4GCSqGSIb3 +MIIHwQYJKoZIhvcNAQcCoIIHsjCCB64CAQExCTAHBgUrDgMCGjCCBc4GCSqGSIb3 DQEHAaCCBb8EggW7eyJhY2Nlc3MiOiB7InNlcnZpY2VDYXRhbG9nIjogW3siZW5k cG9pbnRzIjogW3siYWRtaW5VUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo4Nzc2L3Yx LzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdhIiwgInJlZ2lvbiI6ICJy @@ -30,12 +30,15 @@ ZSwgImRlc2NyaXB0aW9uIjogbnVsbCwgIm5hbWUiOiAidGVuYW50X25hbWUxIiwg ImlkIjogInRlbmFudF9pZDEifX0sICJ1c2VyIjogeyJ1c2VybmFtZSI6ICJ1c2Vy X25hbWUxIiwgInJvbGVzX2xpbmtzIjogWyJyb2xlMSIsInJvbGUyIl0sICJpZCI6 ICJ1c2VyX2lkMSIsICJyb2xlcyI6IFt7Im5hbWUiOiAicm9sZTEifSwgeyJuYW1l -IjogInJvbGUyIn1dLCAibmFtZSI6ICJ1c2VyX25hbWUxIn19fQ0KMYIBSTCCAUUC +IjogInJvbGUyIn1dLCAibmFtZSI6ICJ1c2VyX25hbWUxIn19fQ0KMYIByjCCAcYC AQEwgaQwgZ4xCjAIBgNVBAUTATUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTES MBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQKEwlPcGVuU3RhY2sxETAPBgNVBAsT CEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZrZXlzdG9uZUBvcGVuc3RhY2sub3Jn MRQwEgYDVQQDEwtTZWxmIFNpZ25lZAIBETAHBgUrDgMCGjANBgkqhkiG9w0BAQEF -AASBgEWUF++cnK20YBvO8kcIsVkCsg3M+oVAHGleCQZr8ho2yvgQ06hlPYl95Ih6 -+wIHsUlO1EUxCmNBAdydGDzuonWvkHMN/KMv/PW4EbiuawpvqYYLxqRg3ADjIMNl -fxcgEbY34WAe3dYs2IAGiN70jFbqTr3ltxWHRTeeAqeltio9 +AASCAQCAtuVtqTU9h1uaRrYU1eusSnHwD6jizp/xltTrYTyFPfYjhJdglS+bjSeS +Iau9pN3Tfug98ozUTJ5ByNepAQtxBxPz5bDXhBmAbU6ywaolqRAG+b/s2ShNGQ2a +tn80NeZmDNbtoqdHVAkD3EZXjsEKr2w+3JTTF2indzczyGe5EeSfNUaT+ZhNEmPR +Urob62t8atW+zehCSurpaa8pC5m1NcbK8Uu6Y+qO2m08KU9w5kmbOQtWAGCmtpIx +F2yM1AbSgd90yzen7dv5mNkgZyzQ6SYgRUvkKOKnCyBb97EZK3ZR4qUxQzRYM++8 +g8HdaIfoYVPoPHqODet8Xmhw/Wtp -----END CMS----- diff --git a/examples/pki/cms/auth_token_unscoped.pem b/examples/pki/cms/auth_token_unscoped.pem index 4b073e98..60649090 100644 --- a/examples/pki/cms/auth_token_unscoped.pem +++ b/examples/pki/cms/auth_token_unscoped.pem @@ -1,17 +1,19 @@ -----BEGIN CMS----- -MIICpwYJKoZIhvcNAQcCoIICmDCCApQCAQExCTAHBgUrDgMCGjCCATUGCSqGSIb3 +MIIDKAYJKoZIhvcNAQcCoIIDGTCCAxUCAQExCTAHBgUrDgMCGjCCATUGCSqGSIb3 DQEHAaCCASYEggEieyJhY2Nlc3MiOiB7InRva2VuIjogeyJleHBpcmVzIjogIjIw MTItMDgtMTdUMTU6MzU6MzRaIiwgImlkIjogIjAxZTAzMmM5OTZlZjQ0MDZiMTQ0 MzM1OTE1YTQxZTc5In0sICJzZXJ2aWNlQ2F0YWxvZyI6IHt9LCAidXNlciI6IHsi dXNlcm5hbWUiOiAidXNlcl9uYW1lMSIsICJyb2xlc19saW5rcyI6IFtdLCAiaWQi OiAiYzljODllM2JlM2VlNDUzZmJmMDBjNzk2NmY2ZDNmYmQiLCAicm9sZXMiOiBb eyduYW1lJzogJ3JvbGUxJ30seyduYW1lJzogJ3JvbGUyJ30sXSwgIm5hbWUiOiAi -dXNlcl9uYW1lMSJ9fX0xggFJMIIBRQIBATCBpDCBnjEKMAgGA1UEBRMBNTELMAkG +dXNlcl9uYW1lMSJ9fX0xggHKMIIBxgIBATCBpDCBnjEKMAgGA1UEBRMBNTELMAkG A1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlTdW5ueXZhbGUxEjAQBgNV BAoTCU9wZW5TdGFjazERMA8GA1UECxMIS2V5c3RvbmUxJTAjBgkqhkiG9w0BCQEW FmtleXN0b25lQG9wZW5zdGFjay5vcmcxFDASBgNVBAMTC1NlbGYgU2lnbmVkAgER -MAcGBSsOAwIaMA0GCSqGSIb3DQEBAQUABIGAvJ19wdrQi3umLzaUAt1Ju9Vrr0m9 -vvMEACRBGSiJB8J3R0VaSOqMb6QQYUhddrcaBX70roTA0W0fwU5vNShcTC/zvHSH -uj8FpotvJLj0YiVzzhpYzKXN6vqBIryhKm5SE6MXBmRULuyPSpIGgLCYlAIaOwdD -5s96C9aQukos8sU= +MAcGBSsOAwIaMA0GCSqGSIb3DQEBAQUABIIBAFyD9IH2bXsafCTyHEWS28zBuq03 +ZNWXV4+0BfdMbX1ONkaQ7mLGRmfabLHwfE5RaSASFh/Doq7KTc8XrBVfTm9HQPGr +TLZUawdYlyBFVq0PEE1cPvO9Blz4X/2Awcp/Q67YRd/oLCY2dFWMClMroXu1fy3P +oFlpWPPhURrbU1GjhUgPIz0IxNGjfWEHVsb5kz7Bo4E8J3pgIkccm97XZZtiCwf7 +DVNj+Eb5mRegGG6IgSSRpZULgnCmSofQ3RnW3jSCkDxLXDQm9IsaaLJsuUFLylGs +mB/98w9mP192IGl5MVr8/tANXwb5ok2VatUp/Ww1U0IlWbhN374PbK76vcE= -----END CMS----- diff --git a/examples/pki/cms/revocation_list.pem b/examples/pki/cms/revocation_list.pem index a69278f9..bd22d3f2 100644 --- a/examples/pki/cms/revocation_list.pem +++ b/examples/pki/cms/revocation_list.pem @@ -1,12 +1,15 @@ -----BEGIN CMS----- -MIIB2QYJKoZIhvcNAQcCoIIByjCCAcYCAQExCTAHBgUrDgMCGjBpBgkqhkiG9w0B +MIICWgYJKoZIhvcNAQcCoIICSzCCAkcCAQExCTAHBgUrDgMCGjBpBgkqhkiG9w0B BwGgXARaeyJyZXZva2VkIjpbeyJpZCI6IjdhY2ZjZmRhZjZhMTRhZWJlOTdjNjFj NTk0N2JjNGQzIiwiZXhwaXJlcyI6IjIwMTItMDgtMTRUMTc6NTg6NDhaIn1dfQ0K -MYIBSTCCAUUCAQEwgaQwgZ4xCjAIBgNVBAUTATUxCzAJBgNVBAYTAlVTMQswCQYD +MYIByjCCAcYCAQEwgaQwgZ4xCjAIBgNVBAUTATUxCzAJBgNVBAYTAlVTMQswCQYD VQQIEwJDQTESMBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQKEwlPcGVuU3RhY2sx ETAPBgNVBAsTCEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZrZXlzdG9uZUBvcGVu c3RhY2sub3JnMRQwEgYDVQQDEwtTZWxmIFNpZ25lZAIBETAHBgUrDgMCGjANBgkq -hkiG9w0BAQEFAASBgK0KiADUUObQfhVE/zfyqQI/ROjRODXonVwAJE3WydMHHdXa -TwY/wVTaK0PwvrM/uIph6KOxwH4QelP3V1zRh0SJKERHK1ftJ8xCSxQ4zFwtFzG4 -JTiPDhQcSi1swrUqy6WfVthCJKrLuTnqCP4bTE4bC8DNzMNvilRylNxSQK4g +hkiG9w0BAQEFAASCAQC2f05VHM7zjNT3TBO80AmZ00n7AEWUjbFe5nqIM8kWGM83 +01Bi3uU/nQ0daAd3tqCmDL2EfETAjD+xnIzjlN6eIA74Vy51wFD/KiyWYPWzw8mH +WcATHmE4E8kLdt8NhUodCY9TCFxcHJNDR1Eai/U7hH+5O4p9HcmMjv/GWegZL6HB +Up9Cxu6haxvPFmYylzM6Qt0Ad/WiO/JZLPTA4qXJEJSa9EMFMb0c2wSDSn30swJe +7J79VTFktTr2djv8KFvaHr4vLFYv2Y3ZkTeHqam0m91vllxLZJUP5QTSHjjY6LFE +5eEjIlOv9wOOm1uTtPIq6pxCugU1Wm7gstkqr55R -----END CMS----- diff --git a/examples/pki/private/cakey.pem b/examples/pki/private/cakey.pem index e73c13fc..86ff4cfa 100644 --- a/examples/pki/private/cakey.pem +++ b/examples/pki/private/cakey.pem @@ -1,16 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALzI17ExCaqdr7xY -2Q5CBZ1bW1lsrXxS8eNJRdQtskDuQVAluY03/OGZd8HQYiiY/ci2tYy7BNICbh5G -aO95eqTDykJR3liOYE/tHbY6puQlj2ZivmhlSd2d5d7lF0/H28RQsLu9VktMuw6q -9DpDm35jfrr8LgSeA3MdVqcS/4OhAgMBAAECgYEAjY9xJd5mqDicCXj6MhXRzgAu -TK0QnhQ4a72LDiLB8qx171qKe9mK18RTp9LReC3Yx8Qx+PhYEf5egnc7wq7uBgsk -wAE7bPXBPRoxFxDHtZDRASAhWxX0gkfyO3uIy88HIiQlu51v1O4mSVyNpOZFnY2b -ygLw8lg4AUJibSwE+50CQQDjWKluxXnifqoCn18BeT0FokBmV6ZLnRvHaroJP73O -kPDINiBRPxDpX1cQpQ4hXkjSRM9RrUa4Z6hAEmAUGcoPAkEA1JP7omqY6bRH+tmE -fM503jP5YiGNPB2UJRDPTXnbylII+pwf+hP0aW+2hnjm0cTAJ2yBNd9UnclLBsFO -yABHTwJBAJIvp7s3tfkjE3TeP7v11nwx6ZElWSQT4RHomblqyET0RC+pRjyX/eri -SFzGlYB1XQQABQNzFR9sX+7bIfaq4pcCQCHs1/zMnEi3z8D109IDNN19V/BUQHD2 -m3zq2NqZdv0r6GjuX6AObTQicvO0+clCaBQimeBaGuvvgvy5/vOmL7sCQQDgFxy/ -Yn5c6/jZDf2Vd/Jdk9tdV7147nC/A93c08BIWhD+jgPe/eIYMch61y7VczXizlb7 -M/BPhTX0/4yrL5Pg +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCh1U+N3g2cjFi7 +GeVf21FIv8MDhughFCey9rysAuqFONSFYo2rectLgpDtVy4BFFUFlxmh8Ci9TEZ5 +LiA31tbc4584GxvlLt4dg8aFsUJRBKq0L9i7W5v9uFpHrY1Zr+P4vwG+v7IWOuzw +19f517eGpp6LLcj2vrpN9Yb63rrydKOqr0KJodMd+vFKmi+euFcPqs6sw1OiC5Dp +JN479CGl2Fs1WzMoKDedRNiXG7ysrVrYQIkfMBABBPIwilq1xXZz9Ybo0PbNgOu6 +xpSsy9hq+IzxcwYsr5CwIcbqW6Ju+Ti2iBEaff20lW7dFzO4kwrcqOr9Jnn7qE8Y +fJo9Hyj3AgMBAAECggEAPeEVaTaF190mNGyDczKmEv4X8CpOag+N2nVT0SXQTJ5d +TJ9RckbAwB+tkMLr+Uev9tI+39e3jCI1NDK56QAB6jYy9D4RXYGdNoXji80qgVYa +e4lsAr/Vlp8+DfhDew6xSbSnUytzSeLAJJsznvmn2Bmvt6ILHKXzEMoYEabGrtvk +0n31mmd6sszW6i1cYEhr3gK/VXaO4gM1oWit9aeIJDg3/D3UNUW7aoCTeCz91Gif +87/JH3UIPEIt960jb3oV7ltajRSpiSOfefJFwz/2n09+/P/Sg1+SWAraqkqaLqhO +zoslYSYUuOQv+j97iD/tDVBjiWR1TrzQjf/3noOl+QKBgQDTExaIe0YYI8KdBNZ6 +1cG3vztNWDh0PaP1n0n/bJYAGmAfxfn/gSrABXfeIAjy01f76EK2lPa/i8+DR7vL +dJnUMO10OxaIZKr+OtR1XrMM6kREj6H5yHTNz0sJ3hDEfwJ1BndqwrXlCLAe7upe +veXI9LVfPjPVmf8t9UwyxtaNiwKBgQDERzCGEuyKIeSfgytcdknJ0W+AbdkshC92 +tZQPbI35YOLac2/y7GMjjf5Xg5VJRIYwXAG8ha+61Tvd7+qCVdzNyYfyOoBEE69B +Gc9UdpXRfIjxokfidqh7mIIfjFNSI/UyVmvL9wrregXPcM+s7OlLC/0O82gOcNxU +GKF3oP5XxQKBgQCPZEZIjcZ+m7yYQzMZ26FwnL9Cug4QGdgLAx2YIkJ8624l568A +ftV2AcD+67Boll8NSSoZM3W1htuAifjwLNRcLKkD7yhNnGX1tC2lVqI4weWC1jjp +od6H+q01lOC7PLWEntH9ey1q3M4ZFaGunz89l9CnVXCNScLri9sqG56iJQKBgHOc +50UiInhe7HbU4ZauClq5Za9FhRXGqtqGrDbFn38UBavdMUTq3p6Txgwwcp/coBoe +J9uu90razU+2QPESuGPy4IPa17DB04pKNKiwzSC+9T83cpY/hJCAzazdkDqi+Yv0 +Abz7wE/h6Ug+T+WxCt3sqtvCnjlbWzyh4YJAr3BtAoGBAIibPCEfVOwOfMOXkhIb +liRVVGNxXQa6MwGVVfyR9gmlM85IjcBjh+Tf5+v3Mo286OlzLXQjfYW5pXR5Mgaw +bKe+z5AqJlOsA+lJGTyCNnPKwaXAYHt8dZ41WhgzekibHCx7EQ+8jH1jkz2Gwou6 +MDbnRu+e0FCyRFSuhB9Cim/K -----END PRIVATE KEY----- diff --git a/examples/pki/private/signing_key.pem b/examples/pki/private/signing_key.pem index df9b64db..acf84761 100644 --- a/examples/pki/private/signing_key.pem +++ b/examples/pki/private/signing_key.pem @@ -1,16 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANBnphDSfn7OTmk/ -JOLgOxE0QwP6F/7VCglQH8X2L3hwHUKhCg3FG7YXV054ZAZ79DmSKcQT8cERGUmS -tiP4XpD6wSC2eFEs6MxQoLnVwON0DJAZXLkPlTiNv6uR+M9pJ8WnsbAYz3iF+w/T -aMLU2BZToEqgosfMViHDVtcdRJ9XAgMBAAECgYAqcJEO5+6+oACzyhoW4ZblwADN -tIZibLvofZqa07GDE0HCKc1EVJl6EXLEFhw4fdGUT8GVnoIi0PqXUvsohBGtkmpM -Ee+Yj5ii7VEL75Z5zzJZ50CM7vI0AqZ2WMIITjgsrMKdBh0tHolTCqenqv1t2/OZ -dwAgPG1C90VsPgLW4QJBAOvuCwOZwAOlIygeSYfl9/aQuIQzP5yIQbv95Z+jeyii -ly29FrPqhZvU4+hS7xUnT8X1d5XemsQTScoE/lF3LEkCQQDiIi5crENMdYX60ax7 -/6U25Ej0XyQ3Gt8ryYDoPIaeWSlRV5TQnYfY9CdQqJmTyBWYHNBOhjHupNX4AgWJ -8y6fAkEAlYNZP4LkCGtSiE4JUzINnhfAlybTHSPMZJJWPoCfv/Sp0baO+J2a5lJX -zBcipEkxaMZSbouPkMqYbIoVkRLw4QJAD8y5looGrbnsYYjy1zsWbQ5oNoLLQfpj -q2iJ1DAea8PpCiDnaegHzNXKRW1yRYwOTjF9MG9Z38WumYRypJ/UGwJBAJShOlyg -AA3ob9ajlJ3/NMNbIrVbDuG1c14HVHarnF9nrf8wmjACXP/rjFZo9tVAbQjG6kXH -41oYgyhOVRYT578= +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEwuiHTXfQoNQ7 +IXK0+YEVURd+pxJo0gPUFnYpOwfduTyu9FOBeo+Kc/+SS+6ZSKP/KyeIyc/XHBO5 +tIgPiLgAbRIRMF5Bva4+OzstCeGcgxkoditQZe/DwPc8V0s8rFE0owSnQIdvXT2G +yWO3IGSdLgtwLX1XHmIgDiIteEnRXmdC2Sw1wbi2qlJkjK5isCfcADDgm/42wT/f +92HHdBmI5b60gVOAam/PzR2rMjuA6TzevDgKMg+a+Y1LVfEGTdN1IyLKLsfHtJay ++vjFbSaNDn1r5Uq5c0uRykq8mPrqqkBLsbWSqSTNjFfObo743PHg0goYdrIYQ4wX +ptxSJRylAgMBAAECggEBAIDQPVz/CXarI+ZGQotaYPisqx3+kN3QyDLcNaVOgRrW +P3UmfVjh/QEeae3ECkONu9e8z9gMjyX7uqo0F3NcBWI6Bb79FGgjnuQc8OPOeUZ2 +yUyk+DxdT/eu5+04FQh2o387TjuU0lXFDBem1sI30cbZMyHQliMnwAPOXO+5tVH8 +PusGNBMVvoCyfnj52uVjmAjPqLXyOMcKEhuJFbhnUURKvzkHRf43SWQsb081eh2m +ACQ7uNzX7vg3aPXxSZXY2+hHX67POdqosjddu6CfoXcEHAOAUujvTOFvd1gGRkRo +uOi5hNQqcN5uaqeq9enVThINDyFMzngZBhMCzRTWeK0CgYEA4qUhB7lJZLt9niDW +4Fudda1Pzu3XfxHsSG4D+xx5LunKb3ChG5x7PSLJvusfvnkm5fqhEEhbSVARo6Vn +AAA52u5SPDDNwyk1ttvBR/Fc7eGwpbRQry2I6ui6baKiIOSV2K3vJlsSK8/GMQqu +j0fstJuSvQR7Y6NUYxlWi+VNussCgYEA3j7tFAdGFc5JkeTHSzsU4h2+17uVDSSi +yr7Duc9+9fwAbsO4go9x1CAOvV2r0WX10jPsTGg1d31pWLvJrS6QsAffmM+A0QIT +eBX+umcavXWy69VExWa0xKU9wTE/nQvX9Fr8A+Klh/WfMcvoomK2zgOKoRSmes04 +WKYlHWsSaE8CgYBUYcZ6abG5n1SVmwRlY7asKWqdUE/7L2EZVlyFEYTMwp5r/zL8 +ZLY9fMZAHqoi8FhbJ4Tv2wChuv3WP66pgWwI5tIXNtRk5OLqwcakUmiW6IAsMYYY +sotXam5+gx55wKFJmvh+/0k0ppbTi3aSQeUPGRz44sJNxnGUs8pVK3pVIQKBgQDD +ga+lEtEAlbv6b7sx3wN79pbPyOBR84yRtkcPygzx74Gh7uL9V5rW9GyDAUgIqR0a +kTqp7HI8b0KhIHFFu9TkRcjY8JFtS9o8pXy0FcdcK5H+DFq3HKag5ovwy5YeXTDY +cMGJ2XOsqtIkSDCZySTvDgaBtVzOYoHS2jWEL5C92QKBgGmL2juXIB+HAi7UuKPg +nWkVTikt5Zr2GNgYtso75E7+ljaRuf4D9eEBiOD1qYKQm8KvsiVzEs71BSmT1p1C +b2hlM/5Crb7KumIkHTARQFr5NPwuBZ6NA6RLnd++vKi0WgOJtDAlR3bgwugfQdzZ +4Isaq9Rgfa/EHCKB2weQ7c3r -----END PRIVATE KEY----- diff --git a/examples/pki/private/ssl_key.pem b/examples/pki/private/ssl_key.pem index 2002bde6..e2e68379 100644 --- a/examples/pki/private/ssl_key.pem +++ b/examples/pki/private/ssl_key.pem @@ -1,16 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANRG3ZkIJ+NaY9sm -irkZ+Lzf1Ka18xOvc2kizemUMeAchs9hlP0Kpm8EBHal1vgzSuXncP8gyQ6nMZUw -5NhFMZ1kLSfzoB/hCyTlIp/4VZbCAtn43zlTUSgQQMH+6I4k4sZDOiIAE7yvzEMa -71RkqBzduuFoeuhBm5oqmRa8kac5AgMBAAECgYBngOI94tcoKQO1cJaFaJ964Jyc -aO1L9OmOIvVJ5gNnpiEpbwgpVY8PZGMUwwoNXV0wumfDTmYaafVoLD35IcvtcS3D -Tmsm+zC3ZQYzbQrIkQrtXE+y4bMwtscOTd61YDFQE++0omg3qckVu8IYSdFtTb9D -SjSsWMnYoDmGrBqCHQJBAP2jq2I5fMPSR3LY5FdejwhyUcqs6AKyJD0BDJzIhdV6 -d0InWWss/atR4sMnOX7WKIo1m4+X+0+T2F69kj9hge8CQQDWQKTvbvlDugiziwNc -FRl+yC7YTJ34toRFI4xbszKL3vgk4KDgfSQeoPp9KeHXmjgTfXIOwSVI83QBoL1d -LHFXAkEAglD9VVJEEDiSDSfy6hDjXGugKon8CqaMh+tqF4PPf4eUjqC5CJ/tFYDV -CX+1wr01xw0UCAsGTDSiDstHwNjQcQJAAkF3+xVeBnqE8O77wBJwzEbrR1e3KhEx -31B6f9SpKZPVZP4Ac5ydrrzfJkY0nIKBKKNfegxKijQV+pZop/x5zQJASGTmKcW2 -WKj4P8PiolVlWH2ZTARSschff5wDV6nBneb5zWNgpPORrSRPl9yrYrgqk4vvjLh5 -rUiR/G65ZjmbnA== +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5dpW18l3bs+Mc +j/JdhaAa+qw1RJwShm06g+q38ZoCcCmRO3/XyHghgHWdVa+FKVm2ug923dE2PW4G +SI1pZa3iqbT9Yj70nxN+0l94iym+v9/P7irolvo5OWBbBIJT1Ubjps5fJ//gz6Bd +mwS0FuOy2qfKPnPhyBDH2VawtOgYMLk+PSG3YQh7vM2YvDALPTPz/f4qPmhQpb69 +KBJQElFXPQ9Nu0ABCPWWC2tN87L5pakFw5zq46pttSJ7Izc8MXh3KQrh9FvjmiQu +RnkMvQ/g887Sp6nEJ22ABPEFhuRr89aup6wRD2CkA/8L3zSB5BV7tTK4hQiq07cT +nV9Dv6bfAgMBAAECggEBAIB1K5L/kZUITulMptGyKUgmkjq/D98g7u0Vy/CmTkcc +Cx6F+LGsL9D8mfplDBKOpo4S530sfKk1+Uwu2ovDGqKhazQJ5ZMnz6gK7Ieg1ERD +wDDURTIeyKf0HtJMGD0av2QU+GIeYXQEO446PhLCu+n42zkQ8tDS8xSJbCsu0odV +ok6+i7nEg9sP4uDfAAtM8CUJbRpFTha+m2a7pOz3ylU7/ZV4FDIgJ+FEynaphXAo +bZE4MX5I7A4DDBp7/9g9HsgefByY4xiABuk7Rsyztyf2TrJEtcsVhiV4sCIIHsow +u60KGEcTQWj4npBIMgW1QUdrwmAAh/35gOjt9ZndgTkCgYEA2yT5DmihjVaNF65B +8VtdFcpESr8rr6FBmJ7z31m7MufeV1Inc5GqCK9agRmpr5sTYcgFB9it2IhW2WsA +xHv+7J04bd9DBtgTv58GWrISsCR/abMZnJrm+F5Rafk77jwjCx/SwFj79ybI83Ia +VJYMd7jqkxc00+DZT/3QWZqRrlsCgYEA2KeBBqUVdCpwNiJpgFM18HWjJx36HRk7 +YoFapXot/6R6A/rYmS+/goBZt2CWqqGtnXqWEZvH+v4L+WlUmYQrWwtoxpdR1oXz +EmlCxN7D9MbRVR7QVW24h5zdwPOlbCTGoKzowOs8UEjMfQ81zoMinLmcJgHQSyzs +OawgSF+DmM0CgYBQz26EELNaMktvKxQoE3/c9CyAv8Q1TKqqxBq8BxPP7s7/tkzU +AigIcdlW+Aapue7IxQCN5yocShJ0tE+hJPRZfpR7d7P4xx9pLxQhx766c4sEiEXu +iPSZK/artHuUG1r01DRcN7QabJP3qeDpxjcswuTFfu49H5IjPD5jfGsyNwKBgFjh +bvdQ5lo/xsUOnQV+HZTGTeaQT7l8TnZ85rkYRKKp0TysvgsqIYDiMuwd/fGGXnlK +fyI+LG51pmftpD1OkZLKPXOrRHGjhjK5aCDn2rAimGI5P/KsDpXj7r1ntyeEdtAX +32y1lIrDMtDjWomcFqkBJGQbPl540Xhfeub1+EDJAoGAUZGPT2itKnxEFsa1SKHW +yLeEsag/a9imAVyizo1WJn2WJaUhi1aHK49w6JRowIAzXXb7zLQt7BL8v+ydPVw3 +eySpXGqFuN/Prm3So0SeWllWcPsKFAzjgE0CWjNuB0GlAZGOaJOcWUNoOZjX/SDC +FpolIoaSad28tGc8tbEk3fU= -----END PRIVATE KEY----- diff --git a/keystone/assignment/__init__.py b/keystone/assignment/__init__.py new file mode 100644 index 00000000..5a848308 --- /dev/null +++ b/keystone/assignment/__init__.py @@ -0,0 +1,18 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# flake8: noqa + +# Copyright 2013 OpenStack LLC +# +# 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. + +from keystone.assignment.core import * diff --git a/doc/source/_templates/.placeholder b/keystone/assignment/backends/__init__.py index e69de29b..e69de29b 100644 --- a/doc/source/_templates/.placeholder +++ b/keystone/assignment/backends/__init__.py diff --git a/keystone/assignment/backends/kvs.py b/keystone/assignment/backends/kvs.py new file mode 100644 index 00000000..30d7b2eb --- /dev/null +++ b/keystone/assignment/backends/kvs.py @@ -0,0 +1,499 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2012 OpenStack LLC +# +# 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. + +from keystone import assignment +from keystone import clean +from keystone.common import dependency +from keystone.common import kvs +from keystone import exception +from keystone import identity + + +@dependency.requires('identity_api') +class Assignment(kvs.Base, assignment.Driver): + def __init__(self): + super(Assignment, self).__init__() + + # Public interface + + def get_project(self, tenant_id): + try: + return self.db.get('tenant-%s' % tenant_id) + except exception.NotFound: + raise exception.ProjectNotFound(project_id=tenant_id) + + def list_projects(self, domain_id=None): + project_keys = filter(lambda x: x.startswith("tenant-"), + self.db.keys()) + project_refs = [self.db.get(key) for key in project_keys] + + if domain_id: + self.get_domain(domain_id) + project_refs = filter(lambda x: domain_id in x['domain_id'], + project_refs) + return project_refs + + def get_project_by_name(self, tenant_name, domain_id): + try: + return self.db.get('tenant_name-%s' % tenant_name) + except exception.NotFound: + raise exception.ProjectNotFound(project_id=tenant_name) + + def get_project_users(self, tenant_id): + self.get_project(tenant_id) + user_keys = filter(lambda x: x.startswith("user-"), self.db.keys()) + user_refs = [self.db.get(key) for key in user_keys] + user_refs = filter(lambda x: tenant_id in x['tenants'], user_refs) + return [identity.filter_user(user_ref) for user_ref in user_refs] + + def _get_user(self, user_id): + try: + return self.db.get('user-%s' % user_id) + except exception.NotFound: + raise exception.UserNotFound(user_id=user_id) + + def _get_user_by_name(self, user_name, domain_id): + try: + return self.db.get('user_name-%s' % user_name) + except exception.NotFound: + raise exception.UserNotFound(user_id=user_name) + + def _get_metadata(self, user_id=None, tenant_id=None, + domain_id=None, group_id=None): + try: + if user_id: + if tenant_id: + return self.db.get('metadata-%s-%s' % (tenant_id, + user_id)) + else: + return self.db.get('metadata-%s-%s' % (domain_id, + user_id)) + else: + if tenant_id: + return self.db.get('metadata-%s-%s' % (tenant_id, + group_id)) + else: + return self.db.get('metadata-%s-%s' % (domain_id, + group_id)) + except exception.NotFound: + raise exception.MetadataNotFound() + + def get_role(self, role_id): + try: + return self.db.get('role-%s' % role_id) + except exception.NotFound: + raise exception.RoleNotFound(role_id=role_id) + + def list_roles(self): + role_ids = self.db.get('role_list', []) + return [self.get_role(x) for x in role_ids] + + def get_projects_for_user(self, user_id): + user_ref = self._get_user(user_id) + return user_ref.get('tenants', []) + + def add_role_to_user_and_project(self, user_id, tenant_id, role_id): + self.identity_api.get_user(user_id) + self.get_project(tenant_id) + self.get_role(role_id) + try: + metadata_ref = self._get_metadata(user_id, tenant_id) + except exception.MetadataNotFound: + metadata_ref = {} + + try: + metadata_ref['roles'] = self._add_role_to_role_dicts( + role_id, False, metadata_ref.get('roles', []), + allow_existing=False) + except KeyError: + msg = ('User %s already has role %s in tenant %s' + % (user_id, role_id, tenant_id)) + raise exception.Conflict(type='role grant', details=msg) + + self._update_metadata(user_id, tenant_id, metadata_ref) + + def remove_role_from_user_and_project(self, user_id, tenant_id, role_id): + try: + metadata_ref = self._get_metadata(user_id, tenant_id) + except exception.MetadataNotFound: + metadata_ref = {} + + try: + metadata_ref['roles'] = self._remove_role_from_role_dicts( + role_id, False, metadata_ref.get('roles', [])) + except KeyError: + raise exception.RoleNotFound(message=_( + 'Cannot remove role that has not been granted, %s') % + role_id) + + if len(metadata_ref['roles']): + self._update_metadata(user_id, tenant_id, metadata_ref) + else: + + self.db.delete('metadata-%s-%s' % (tenant_id, user_id)) + user_ref = self._get_user(user_id) + tenants = set(user_ref.get('tenants', [])) + tenants.remove(tenant_id) + user_ref['tenants'] = list(tenants) + self.identity_api.update_user(user_id, user_ref) + + def list_role_assignments(self): + """List the role assignments. + + The kvs backend stores role assignments as key-values: + + "metadata-{target}-{actor}", with the value being a role list + + i.e. "metadata-MyProjectID-MyUserID" [{'id': role1}, {'id': role2}] + + ...so we enumerate the list and extract the targets, actors + and roles. + + """ + assignment_list = [] + metadata_keys = filter(lambda x: x.startswith("metadata-"), + self.db.keys()) + for key in metadata_keys: + template = {} + meta_id1 = key.split('-')[1] + meta_id2 = key.split('-')[2] + try: + self.get_project(meta_id1) + template['project_id'] = meta_id1 + except exception.NotFound: + template['domain_id'] = meta_id1 + try: + self._get_user(meta_id2) + template['user_id'] = meta_id2 + except exception.NotFound: + template['group_id'] = meta_id2 + + entry = self.db.get(key) + for r in self._roles_from_role_dicts(entry.get('roles', {}), + False): + role_assignment = template.copy() + role_assignment['role_id'] = r + assignment_list.append(role_assignment) + + return assignment_list + + # CRUD + def create_project(self, tenant_id, tenant): + tenant['name'] = clean.project_name(tenant['name']) + try: + self.get_project(tenant_id) + except exception.ProjectNotFound: + pass + else: + msg = 'Duplicate ID, %s.' % tenant_id + raise exception.Conflict(type='tenant', details=msg) + + try: + self.get_project_by_name(tenant['name'], tenant['domain_id']) + except exception.ProjectNotFound: + pass + else: + msg = 'Duplicate name, %s.' % tenant['name'] + raise exception.Conflict(type='tenant', details=msg) + + self.db.set('tenant-%s' % tenant_id, tenant) + self.db.set('tenant_name-%s' % tenant['name'], tenant) + return tenant + + def update_project(self, tenant_id, tenant): + if 'name' in tenant: + tenant['name'] = clean.project_name(tenant['name']) + try: + existing = self.db.get('tenant_name-%s' % tenant['name']) + if existing and tenant_id != existing['id']: + msg = 'Duplicate name, %s.' % tenant['name'] + raise exception.Conflict(type='tenant', details=msg) + except exception.NotFound: + pass + # get the old name and delete it too + try: + old_project = self.db.get('tenant-%s' % tenant_id) + except exception.NotFound: + raise exception.ProjectNotFound(project_id=tenant_id) + new_project = old_project.copy() + new_project.update(tenant) + new_project['id'] = tenant_id + self.db.delete('tenant_name-%s' % old_project['name']) + self.db.set('tenant-%s' % tenant_id, new_project) + self.db.set('tenant_name-%s' % new_project['name'], new_project) + return new_project + + def delete_project(self, tenant_id): + try: + old_project = self.db.get('tenant-%s' % tenant_id) + except exception.NotFound: + raise exception.ProjectNotFound(project_id=tenant_id) + self.db.delete('tenant_name-%s' % old_project['name']) + self.db.delete('tenant-%s' % tenant_id) + + def _create_metadata(self, user_id, tenant_id, metadata, + domain_id=None, group_id=None): + + return self._update_metadata(user_id, tenant_id, metadata, + domain_id, group_id) + + def _update_metadata(self, user_id, tenant_id, metadata, + domain_id=None, group_id=None): + if user_id: + if tenant_id: + self.db.set('metadata-%s-%s' % (tenant_id, user_id), metadata) + user_ref = self._get_user(user_id) + tenants = set(user_ref.get('tenants', [])) + if tenant_id not in tenants: + tenants.add(tenant_id) + user_ref['tenants'] = list(tenants) + self.identity_api.update_user(user_id, user_ref) + else: + self.db.set('metadata-%s-%s' % (domain_id, user_id), metadata) + else: + if tenant_id: + self.db.set('metadata-%s-%s' % (tenant_id, group_id), metadata) + else: + self.db.set('metadata-%s-%s' % (domain_id, group_id), metadata) + return metadata + + def create_role(self, role_id, role): + try: + self.get_role(role_id) + except exception.RoleNotFound: + pass + else: + msg = 'Duplicate ID, %s.' % role_id + raise exception.Conflict(type='role', details=msg) + + for role_ref in self.list_roles(): + if role['name'] == role_ref['name']: + msg = 'Duplicate name, %s.' % role['name'] + raise exception.Conflict(type='role', details=msg) + self.db.set('role-%s' % role_id, role) + role_list = set(self.db.get('role_list', [])) + role_list.add(role_id) + self.db.set('role_list', list(role_list)) + return role + + def update_role(self, role_id, role): + old_role_ref = None + for role_ref in self.list_roles(): + if role['name'] == role_ref['name'] and role_id != role_ref['id']: + msg = 'Duplicate name, %s.' % role['name'] + raise exception.Conflict(type='role', details=msg) + if role_id == role_ref['id']: + old_role_ref = role_ref + if old_role_ref is None: + raise exception.RoleNotFound(role_id=role_id) + new_role = old_role_ref.copy() + new_role.update(role) + new_role['id'] = role_id + self.db.set('role-%s' % role_id, new_role) + return role + + def delete_role(self, role_id): + self.get_role(role_id) + metadata_keys = filter(lambda x: x.startswith("metadata-"), + self.db.keys()) + for key in metadata_keys: + meta_id1 = key.split('-')[1] + meta_id2 = key.split('-')[2] + try: + self.delete_grant(role_id, project_id=meta_id1, + user_id=meta_id2) + except exception.NotFound: + pass + try: + self.delete_grant(role_id, project_id=meta_id1, + group_id=meta_id2) + except exception.NotFound: + pass + try: + self.delete_grant(role_id, domain_id=meta_id1, + user_id=meta_id2) + except exception.NotFound: + pass + try: + self.delete_grant(role_id, domain_id=meta_id1, + group_id=meta_id2) + except exception.NotFound: + pass + self.db.delete('role-%s' % role_id) + role_list = set(self.db.get('role_list', [])) + role_list.remove(role_id) + self.db.set('role_list', list(role_list)) + + def create_grant(self, role_id, user_id=None, group_id=None, + domain_id=None, project_id=None, + inherited_to_projects=False): + + self.get_role(role_id) + if user_id: + self.identity_api.get_user(user_id) + if group_id: + self.identity_api.get_group(group_id) + if domain_id: + self.get_domain(domain_id) + if project_id: + self.get_project(project_id) + + try: + metadata_ref = self._get_metadata(user_id, project_id, + domain_id, group_id) + except exception.MetadataNotFound: + metadata_ref = {} + + metadata_ref['roles'] = self._add_role_to_role_dicts( + role_id, inherited_to_projects, metadata_ref.get('roles', [])) + + self._update_metadata(user_id, project_id, metadata_ref, + domain_id, group_id) + + def list_grants(self, user_id=None, group_id=None, + domain_id=None, project_id=None, + inherited_to_projects=False): + if user_id: + self.identity_api.get_user(user_id) + if group_id: + self.identity_api.get_group(group_id) + if domain_id: + self.get_domain(domain_id) + if project_id: + self.get_project(project_id) + + try: + metadata_ref = self._get_metadata(user_id, project_id, + domain_id, group_id) + except exception.MetadataNotFound: + metadata_ref = {} + + return [self.get_role(x) for x in + self._roles_from_role_dicts(metadata_ref.get('roles', []), + inherited_to_projects)] + + def get_grant(self, role_id, user_id=None, group_id=None, + domain_id=None, project_id=None, + inherited_to_projects=False): + self.get_role(role_id) + if user_id: + self.identity_api.get_user(user_id) + if group_id: + self.get_group(group_id) + if domain_id: + self.get_domain(domain_id) + if project_id: + self.get_project(project_id) + + try: + metadata_ref = self._get_metadata(user_id, project_id, + domain_id, group_id) + except exception.MetadataNotFound: + metadata_ref = {} + + role_ids = set(self._roles_from_role_dicts( + metadata_ref.get('roles', []), inherited_to_projects)) + + if role_id not in role_ids: + raise exception.RoleNotFound(role_id=role_id) + return self.get_role(role_id) + + def delete_grant(self, role_id, user_id=None, group_id=None, + domain_id=None, project_id=None, + inherited_to_projects=False): + self.get_role(role_id) + if user_id: + self.identity_api.get_user(user_id) + if group_id: + self.identity_api.get_group(group_id) + if domain_id: + self.get_domain(domain_id) + if project_id: + self.get_project(project_id) + + try: + metadata_ref = self._get_metadata(user_id, project_id, + domain_id, group_id) + except exception.MetadataNotFound: + metadata_ref = {} + + try: + metadata_ref['roles'] = self._remove_role_from_role_dicts( + role_id, inherited_to_projects, metadata_ref.get('roles', [])) + except KeyError: + raise exception.RoleNotFound(role_id=role_id) + + self._update_metadata(user_id, project_id, metadata_ref, + domain_id, group_id) + + # domain crud + + def create_domain(self, domain_id, domain): + try: + self.get_domain(domain_id) + except exception.DomainNotFound: + pass + else: + msg = 'Duplicate ID, %s.' % domain_id + raise exception.Conflict(type='domain', details=msg) + + try: + self.get_domain_by_name(domain['name']) + except exception.DomainNotFound: + pass + else: + msg = 'Duplicate name, %s.' % domain['name'] + raise exception.Conflict(type='domain', details=msg) + + self.db.set('domain-%s' % domain_id, domain) + self.db.set('domain_name-%s' % domain['name'], domain) + domain_list = set(self.db.get('domain_list', [])) + domain_list.add(domain_id) + self.db.set('domain_list', list(domain_list)) + return domain + + def list_domains(self): + domain_ids = self.db.get('domain_list', []) + return [self.get_domain(x) for x in domain_ids] + + def get_domain(self, domain_id): + try: + return self.db.get('domain-%s' % domain_id) + except exception.NotFound: + raise exception.DomainNotFound(domain_id=domain_id) + + def get_domain_by_name(self, domain_name): + try: + return self.db.get('domain_name-%s' % domain_name) + except exception.NotFound: + raise exception.DomainNotFound(domain_id=domain_name) + + def update_domain(self, domain_id, domain): + orig_domain = self.get_domain(domain_id) + domain['id'] = domain_id + self.db.set('domain-%s' % domain_id, domain) + self.db.set('domain_name-%s' % domain['name'], domain) + if domain['name'] != orig_domain['name']: + self.db.delete('domain_name-%s' % orig_domain['name']) + return domain + + def delete_domain(self, domain_id): + domain = self.get_domain(domain_id) + self.db.delete('domain-%s' % domain_id) + self.db.delete('domain_name-%s' % domain['name']) + domain_list = set(self.db.get('domain_list', [])) + domain_list.remove(domain_id) + self.db.set('domain_list', list(domain_list)) diff --git a/keystone/assignment/backends/ldap.py b/keystone/assignment/backends/ldap.py new file mode 100644 index 00000000..9b273e40 --- /dev/null +++ b/keystone/assignment/backends/ldap.py @@ -0,0 +1,543 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2012-2013 OpenStack LLC +# +# 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. +from __future__ import absolute_import + +import uuid + +import ldap as ldap + +from keystone import assignment +from keystone import clean +from keystone.common import dependency +from keystone.common import ldap as common_ldap +from keystone.common import logging +from keystone.common import models +from keystone import config +from keystone import exception +from keystone.identity.backends import ldap as ldap_identity + + +CONF = config.CONF +LOG = logging.getLogger(__name__) + +DEFAULT_DOMAIN = { + 'id': CONF.identity.default_domain_id, + 'name': 'Default', + 'enabled': True +} + + +@dependency.requires('identity_api') +class Assignment(assignment.Driver): + def __init__(self): + super(Assignment, self).__init__() + self.LDAP_URL = CONF.ldap.url + self.LDAP_USER = CONF.ldap.user + self.LDAP_PASSWORD = CONF.ldap.password + self.suffix = CONF.ldap.suffix + + #These are the only deep dependency from assignment back + #to identity. The assumption is that if you are using + #LDAP for assignments, you are using it for Id as well. + self.user = ldap_identity.UserApi(CONF) + self.group = ldap_identity.GroupApi(CONF) + + self.project = ProjectApi(CONF) + self.role = RoleApi(CONF) + self._identity_api = None + + def get_project(self, tenant_id): + return self._set_default_domain(self.project.get(tenant_id)) + + def list_projects(self, domain_id=None): + # We don't support multiple domains within this driver, so ignore + # any domain passed. + return self._set_default_domain(self.project.get_all()) + + def get_project_by_name(self, tenant_name, domain_id): + self._validate_default_domain_id(domain_id) + return self._set_default_domain(self.project.get_by_name(tenant_name)) + + def create_project(self, tenant_id, tenant): + tenant = self._validate_default_domain(tenant) + tenant['name'] = clean.project_name(tenant['name']) + data = tenant.copy() + if 'id' not in data or data['id'] is None: + data['id'] = str(uuid.uuid4().hex) + if 'description' in data and data['description'] in ['', None]: + data.pop('description') + return self._set_default_domain(self.project.create(data)) + + def update_project(self, tenant_id, tenant): + tenant = self._validate_default_domain(tenant) + if 'name' in tenant: + tenant['name'] = clean.project_name(tenant['name']) + return self._set_default_domain(self.project.update(tenant_id, tenant)) + + def _get_metadata(self, user_id=None, tenant_id=None, + domain_id=None, group_id=None): + + def _get_roles_for_just_user_and_project(user_id, tenant_id): + self.identity_api.get_user(user_id) + self.get_project(tenant_id) + user_dn = self.user._id_to_dn(user_id) + return [self.role._dn_to_id(a.role_dn) + for a in self.role.get_role_assignments + (self.project._id_to_dn(tenant_id)) + if a.user_dn == user_dn] + + if domain_id is not None: + msg = 'Domain metadata not supported by LDAP' + raise exception.NotImplemented(message=msg) + if (not self.get_project(tenant_id) or + not self.identity_api.get_user(user_id)): + return {} + + metadata_ref = _get_roles_for_just_user_and_project(user_id, tenant_id) + if not metadata_ref: + return {} + return {'roles': [self._role_to_dict(r, False) for r in metadata_ref]} + + def get_role(self, role_id): + return self.role.get(role_id) + + def list_roles(self): + return self.role.get_all() + + def get_projects_for_user(self, user_id): + self.identity_api.get_user(user_id) + user_dn = self.user._id_to_dn(user_id) + associations = (self.role.list_project_roles_for_user + (user_dn, self.project.tree_dn)) + return [p['id'] for p in + self.project.get_user_projects(user_dn, associations)] + + def get_project_users(self, tenant_id): + self.get_project(tenant_id) + tenant_dn = self.project._id_to_dn(tenant_id) + rolegrants = self.role.get_role_assignments(tenant_dn) + users = [self.user.get_filtered(self.user._dn_to_id(user_id)) + for user_id in + self.project.get_user_dns(tenant_id, rolegrants)] + return self._set_default_domain(users) + + def _subrole_id_to_dn(self, role_id, tenant_id): + if tenant_id is None: + return self.role._id_to_dn(role_id) + else: + return '%s=%s,%s' % (self.role.id_attr, + ldap.dn.escape_dn_chars(role_id), + self.project._id_to_dn(tenant_id)) + + def add_role_to_user_and_project(self, user_id, tenant_id, role_id): + self.identity_api.get_user(user_id) + self.get_project(tenant_id) + self.get_role(role_id) + user_dn = self.user._id_to_dn(user_id) + role_dn = self._subrole_id_to_dn(role_id, tenant_id) + self.role.add_user(role_id, role_dn, user_dn, user_id, tenant_id) + tenant_dn = self.project._id_to_dn(tenant_id) + return UserRoleAssociation( + role_dn=role_dn, + user_dn=user_dn, + tenant_dn=tenant_dn) + + def _create_metadata(self, user_id, tenant_id, metadata): + return {} + + def create_role(self, role_id, role): + try: + self.get_role(role_id) + except exception.NotFound: + pass + else: + msg = 'Duplicate ID, %s.' % role_id + raise exception.Conflict(type='role', details=msg) + + try: + self.role.get_by_name(role['name']) + except exception.NotFound: + pass + else: + msg = 'Duplicate name, %s.' % role['name'] + raise exception.Conflict(type='role', details=msg) + + return self.role.create(role) + + def delete_role(self, role_id): + return self.role.delete(role_id, self.project.tree_dn) + + def delete_project(self, tenant_id): + if self.project.subtree_delete_enabled: + self.project.deleteTree(id) + else: + tenant_dn = self.project._id_to_dn(tenant_id) + self.role.roles_delete_subtree_by_project(tenant_dn) + self.project.delete(tenant_id) + + def remove_role_from_user_and_project(self, user_id, tenant_id, role_id): + role_dn = self._subrole_id_to_dn(role_id, tenant_id) + return self.role.delete_user(role_dn, + self.user._id_to_dn(user_id), + self.project._id_to_dn(tenant_id), + user_id, role_id) + + def update_role(self, role_id, role): + self.get_role(role_id) + self.role.update(role_id, role) + + def create_domain(self, domain_id, domain): + if domain_id == CONF.identity.default_domain_id: + msg = 'Duplicate ID, %s.' % domain_id + raise exception.Conflict(type='domain', details=msg) + raise exception.Forbidden('Domains are read-only against LDAP') + + def get_domain(self, domain_id): + self._validate_default_domain_id(domain_id) + return DEFAULT_DOMAIN + + def update_domain(self, domain_id, domain): + self._validate_default_domain_id(domain_id) + raise exception.Forbidden('Domains are read-only against LDAP') + + def delete_domain(self, domain_id): + self._validate_default_domain_id(domain_id) + raise exception.Forbidden('Domains are read-only against LDAP') + + def list_domains(self): + return [assignment.DEFAULT_DOMAIN] + +#Bulk actions on User From identity + def delete_user(self, user_id): + user_dn = self.user._id_to_dn(user_id) + for ref in self.role.list_global_roles_for_user(user_dn): + self.role.delete_user(ref.role_dn, ref.user_dn, ref.project_dn, + user_id, self.role._dn_to_id(ref.role_dn)) + for ref in self.role.list_project_roles_for_user(user_dn, + self.project.tree_dn): + self.role.delete_user(ref.role_dn, ref.user_dn, ref.project_dn, + user_id, self.role._dn_to_id(ref.role_dn)) + + user = self.user.get(user_id) + if hasattr(user, 'tenant_id'): + self.project.remove_user(user.tenant_id, + self.user._id_to_dn(user_id)) + + #LDAP assignments only supports LDAP identity. Assignments under identity + #are already deleted + def delete_group(self, group_id): + if not self.group.subtree_delete_enabled: + # TODO(spzala): this is only placeholder for group and domain + # role support which will be added under bug 1101287 + conn = self.group.get_connection() + query = '(objectClass=%s)' % self.group.object_class + dn = None + dn = self.group._id_to_dn(id) + if dn: + try: + roles = conn.search_s(dn, ldap.SCOPE_ONELEVEL, + query, ['%s' % '1.1']) + for role_dn, _ in roles: + conn.delete_s(role_dn) + except ldap.NO_SUCH_OBJECT: + pass + + +# TODO(termie): turn this into a data object and move logic to driver +class ProjectApi(common_ldap.EnabledEmuMixIn, common_ldap.BaseLdap): + DEFAULT_OU = 'ou=Groups' + DEFAULT_STRUCTURAL_CLASSES = [] + DEFAULT_OBJECTCLASS = 'groupOfNames' + DEFAULT_ID_ATTR = 'cn' + DEFAULT_MEMBER_ATTRIBUTE = 'member' + DEFAULT_ATTRIBUTE_IGNORE = [] + NotFound = exception.ProjectNotFound + notfound_arg = 'project_id' # NOTE(yorik-sar): while options_name = tenant + options_name = 'tenant' + attribute_mapping = {'name': 'ou', + 'description': 'description', + 'tenantId': 'cn', + 'enabled': 'enabled', + 'domain_id': 'domain_id'} + model = models.Project + + def __init__(self, conf): + super(ProjectApi, self).__init__(conf) + self.attribute_mapping['name'] = conf.ldap.tenant_name_attribute + self.attribute_mapping['description'] = conf.ldap.tenant_desc_attribute + self.attribute_mapping['enabled'] = conf.ldap.tenant_enabled_attribute + self.attribute_mapping['domain_id'] = ( + conf.ldap.tenant_domain_id_attribute) + self.member_attribute = (getattr(conf.ldap, 'tenant_member_attribute') + or self.DEFAULT_MEMBER_ATTRIBUTE) + self.attribute_ignore = (getattr(conf.ldap, 'tenant_attribute_ignore') + or self.DEFAULT_ATTRIBUTE_IGNORE) + + def create(self, values): + self.affirm_unique(values) + data = values.copy() + if data.get('id') is None: + data['id'] = uuid.uuid4().hex + return super(ProjectApi, self).create(data) + + def get_user_projects(self, user_dn, associations): + """Returns list of tenants a user has access to + """ + + project_ids = set() + for assoc in associations: + project_ids.add(self._dn_to_id(assoc.project_dn)) + projects = [] + for project_id in project_ids: + #slower to get them one at a time, but a huge list could blow out + #the connection. This is the safer way + projects.append(self.get(project_id)) + return projects + + def add_user(self, tenant_id, user_dn): + conn = self.get_connection() + try: + conn.modify_s( + self._id_to_dn(tenant_id), + [(ldap.MOD_ADD, + self.member_attribute, + user_dn)]) + except ldap.TYPE_OR_VALUE_EXISTS: + # As adding a user to a tenant is done implicitly in several + # places, and is not part of the exposed API, it's easier for us to + # just ignore this instead of raising exception.Conflict. + pass + + def remove_user(self, tenant_id, user_dn, user_id): + conn = self.get_connection() + try: + conn.modify_s(self._id_to_dn(tenant_id), + [(ldap.MOD_DELETE, + self.member_attribute, + user_dn)]) + except ldap.NO_SUCH_ATTRIBUTE: + raise exception.NotFound(user_id) + + def get_user_dns(self, tenant_id, rolegrants, role_dn=None): + tenant = self._ldap_get(tenant_id) + res = set() + if not role_dn: + # Get users who have default tenant mapping + for user_dn in tenant[1].get(self.member_attribute, []): + if self.use_dumb_member and user_dn == self.dumb_member: + continue + res.add(user_dn) + + # Get users who are explicitly mapped via a tenant + for rolegrant in rolegrants: + if role_dn is None or rolegrant.role_dn == role_dn: + res.add(rolegrant.user_dn) + return list(res) + + def update(self, id, values): + old_obj = self.get(id) + if old_obj['name'] != values['name']: + msg = 'Changing Name not supported by LDAP' + raise exception.NotImplemented(message=msg) + return super(ProjectApi, self).update(id, values, old_obj) + + +class UserRoleAssociation(object): + """Role Grant model.""" + + def __init__(self, user_dn=None, role_dn=None, tenant_dn=None, + *args, **kw): + self.user_dn = user_dn + self.role_dn = role_dn + self.project_dn = tenant_dn + + +class GroupRoleAssociation(object): + """Role Grant model.""" + + def __init__(self, group_dn=None, role_dn=None, tenant_dn=None, + *args, **kw): + self.group_dn = group_dn + self.role_dn = role_dn + self.project_dn = tenant_dn + + +# TODO(termie): turn this into a data object and move logic to driver +class RoleApi(common_ldap.BaseLdap): + DEFAULT_OU = 'ou=Roles' + DEFAULT_STRUCTURAL_CLASSES = [] + DEFAULT_OBJECTCLASS = 'organizationalRole' + DEFAULT_MEMBER_ATTRIBUTE = 'roleOccupant' + DEFAULT_ATTRIBUTE_IGNORE = [] + NotFound = exception.RoleNotFound + options_name = 'role' + attribute_mapping = {'name': 'ou', + #'serviceId': 'service_id', + } + model = models.Role + + def __init__(self, conf): + super(RoleApi, self).__init__(conf) + self.attribute_mapping['name'] = conf.ldap.role_name_attribute + self.member_attribute = (getattr(conf.ldap, 'role_member_attribute') + or self.DEFAULT_MEMBER_ATTRIBUTE) + self.attribute_ignore = (getattr(conf.ldap, 'role_attribute_ignore') + or self.DEFAULT_ATTRIBUTE_IGNORE) + + def get(self, id, filter=None): + model = super(RoleApi, self).get(id, filter) + return model + + def create(self, values): + return super(RoleApi, self).create(values) + + def add_user(self, role_id, role_dn, user_dn, user_id, tenant_id=None): + conn = self.get_connection() + try: + conn.modify_s(role_dn, [(ldap.MOD_ADD, + self.member_attribute, user_dn)]) + except ldap.TYPE_OR_VALUE_EXISTS: + msg = ('User %s already has role %s in tenant %s' + % (user_id, role_id, tenant_id)) + raise exception.Conflict(type='role grant', details=msg) + except ldap.NO_SUCH_OBJECT: + if tenant_id is None or self.get(role_id) is None: + raise Exception(_("Role %s not found") % (role_id,)) + + attrs = [('objectClass', [self.object_class]), + (self.member_attribute, [user_dn])] + + if self.use_dumb_member: + attrs[1][1].append(self.dumb_member) + try: + conn.add_s(role_dn, attrs) + except Exception as inst: + raise inst + + def delete_user(self, role_dn, user_dn, tenant_dn, + user_id, role_id): + conn = self.get_connection() + try: + conn.modify_s(role_dn, [(ldap.MOD_DELETE, + self.member_attribute, user_dn)]) + except ldap.NO_SUCH_OBJECT: + if tenant_dn is None: + raise exception.RoleNotFound(role_id=role_id) + attrs = [('objectClass', [self.object_class]), + (self.member_attribute, [user_dn])] + + if self.use_dumb_member: + attrs[1][1].append(self.dumb_member) + try: + conn.add_s(role_dn, attrs) + except Exception as inst: + raise inst + except ldap.NO_SUCH_ATTRIBUTE: + raise exception.UserNotFound(user_id=user_id) + + def get_role_assignments(self, tenant_dn): + conn = self.get_connection() + query = '(objectClass=%s)' % self.object_class + + try: + roles = conn.search_s(tenant_dn, ldap.SCOPE_ONELEVEL, query) + except ldap.NO_SUCH_OBJECT: + return [] + + res = [] + for role_dn, attrs in roles: + try: + user_dns = attrs[self.member_attribute] + except KeyError: + continue + for user_dn in user_dns: + if self.use_dumb_member and user_dn == self.dumb_member: + continue + res.append(UserRoleAssociation( + user_dn=user_dn, + role_dn=role_dn, + tenant_dn=tenant_dn)) + + return res + + def list_global_roles_for_user(self, user_dn): + roles = self.get_all('(%s=%s)' % (self.member_attribute, user_dn)) + return [UserRoleAssociation( + role_dn=role.dn, + user_dn=user_dn) for role in roles] + + def list_project_roles_for_user(self, user_dn, project_subtree): + conn = self.get_connection() + query = '(&(objectClass=%s)(%s=%s))' % (self.object_class, + self.member_attribute, + user_dn) + try: + roles = conn.search_s(project_subtree, + ldap.SCOPE_SUBTREE, + query) + except ldap.NO_SUCH_OBJECT: + return [] + + res = [] + for role_dn, _ in roles: + #ldap.dn.dn2str returns an array, where the first + #element is the first segment. + #For a role assignment, this contains the role ID, + #The remainder is the DN of the tenant. + tenant = ldap.dn.str2dn(role_dn) + tenant.pop(0) + tenant_dn = ldap.dn.dn2str(tenant) + res.append(UserRoleAssociation( + user_dn=user_dn, + role_dn=role_dn, + tenant_dn=tenant_dn)) + return res + + def roles_delete_subtree_by_project(self, tenant_dn): + conn = self.get_connection() + query = '(objectClass=%s)' % self.object_class + try: + roles = conn.search_s(tenant_dn, ldap.SCOPE_ONELEVEL, query) + for role_dn, _ in roles: + try: + conn.delete_s(role_dn) + except Exception as inst: + raise inst + except ldap.NO_SUCH_OBJECT: + pass + + def update(self, role_id, role): + if role['id'] != role_id: + raise exception.ValidationError('Cannot change role ID') + try: + old_name = self.get_by_name(role['name']) + raise exception.Conflict('Cannot duplicate name %s' % old_name) + except exception.NotFound: + pass + return super(RoleApi, self).update(role_id, role) + + def delete(self, id, tenant_dn): + conn = self.get_connection() + query = '(&(objectClass=%s)(%s=%s))' % (self.object_class, + self.id_attr, id) + try: + for role_dn, _ in conn.search_s(tenant_dn, + ldap.SCOPE_SUBTREE, + query): + conn.delete_s(role_dn) + except ldap.NO_SUCH_OBJECT: + pass + super(RoleApi, self).delete(id) diff --git a/keystone/assignment/backends/sql.py b/keystone/assignment/backends/sql.py new file mode 100644 index 00000000..cd2a0a5c --- /dev/null +++ b/keystone/assignment/backends/sql.py @@ -0,0 +1,751 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2012-13 OpenStack LLC +# +# 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. + +from keystone import assignment +from keystone import clean +from keystone.common import dependency +from keystone.common import sql +from keystone.common.sql import migration +from keystone import exception + + +@dependency.requires('identity_api') +class Assignment(sql.Base, assignment.Driver): + + # Internal interface to manage the database + def db_sync(self, version=None): + migration.db_sync(version=version) + + def _get_project(self, session, project_id): + project_ref = session.query(Project).get(project_id) + if project_ref is None: + raise exception.ProjectNotFound(project_id=project_id) + return project_ref + + def get_project(self, tenant_id): + session = self.get_session() + return self._get_project(session, tenant_id).to_dict() + + def get_project_by_name(self, tenant_name, domain_id): + session = self.get_session() + query = session.query(Project) + query = query.filter_by(name=tenant_name) + query = query.filter_by(domain_id=domain_id) + try: + project_ref = query.one() + except sql.NotFound: + raise exception.ProjectNotFound(project_id=tenant_name) + return project_ref.to_dict() + + def get_project_user_ids(self, tenant_id): + session = self.get_session() + self.get_project(tenant_id) + query = session.query(UserProjectGrant) + query = query.filter(UserProjectGrant.project_id == + tenant_id) + project_refs = query.all() + return [project_ref.user_id for project_ref in project_refs] + + def get_project_users(self, tenant_id): + self.get_session() + self.get_project(tenant_id) + user_refs = [] + #TODO(ayoung): Move to controller or manager + for user_id in self.get_project_user_ids(tenant_id): + user_ref = self.identity_api.get_user(user_id) + user_refs.append(user_ref) + return user_refs + + def _get_metadata(self, user_id=None, tenant_id=None, + domain_id=None, group_id=None): + session = self.get_session() + + if user_id: + if tenant_id: + q = session.query(UserProjectGrant) + q = q.filter_by(project_id=tenant_id) + elif domain_id: + q = session.query(UserDomainGrant) + q = q.filter_by(domain_id=domain_id) + q = q.filter_by(user_id=user_id) + elif group_id: + if tenant_id: + q = session.query(GroupProjectGrant) + q = q.filter_by(project_id=tenant_id) + elif domain_id: + q = session.query(GroupDomainGrant) + q = q.filter_by(domain_id=domain_id) + q = q.filter_by(group_id=group_id) + try: + return q.one().data + except sql.NotFound: + raise exception.MetadataNotFound() + + def create_grant(self, role_id, user_id=None, group_id=None, + domain_id=None, project_id=None, + inherited_to_projects=False): + if user_id: + self.identity_api.get_user(user_id) + if group_id: + self.identity_api.get_group(group_id) + + session = self.get_session() + self._get_role(session, role_id) + + if domain_id: + self._get_domain(session, domain_id) + if project_id: + self._get_project(session, project_id) + + if project_id and inherited_to_projects: + msg = _('Inherited roles can only be assigned to domains') + raise exception.Conflict(type='role grant', details=msg) + + try: + metadata_ref = self._get_metadata(user_id, project_id, + domain_id, group_id) + is_new = False + except exception.MetadataNotFound: + metadata_ref = {} + is_new = True + + metadata_ref['roles'] = self._add_role_to_role_dicts( + role_id, inherited_to_projects, metadata_ref.get('roles', [])) + + if is_new: + self._create_metadata(user_id, project_id, metadata_ref, + domain_id, group_id) + else: + self._update_metadata(user_id, project_id, metadata_ref, + domain_id, group_id) + + def list_grants(self, user_id=None, group_id=None, + domain_id=None, project_id=None, + inherited_to_projects=False): + if user_id: + self.identity_api.get_user(user_id) + if group_id: + self.identity_api.get_group(group_id) + session = self.get_session() + if domain_id: + self._get_domain(session, domain_id) + if project_id: + self._get_project(session, project_id) + + try: + metadata_ref = self._get_metadata(user_id, project_id, + domain_id, group_id) + except exception.MetadataNotFound: + metadata_ref = {} + + return [self.get_role(x) for x in + self._roles_from_role_dicts(metadata_ref.get('roles', []), + inherited_to_projects)] + + def get_grant(self, role_id, user_id=None, group_id=None, + domain_id=None, project_id=None, + inherited_to_projects=False): + if user_id: + self.identity_api.get_user(user_id) + if group_id: + self.identity_api.get_group(group_id) + + session = self.get_session() + role_ref = self._get_role(session, role_id) + + if domain_id: + self._get_domain(session, domain_id) + if project_id: + self._get_project(session, project_id) + + try: + metadata_ref = self._get_metadata(user_id, project_id, + domain_id, group_id) + except exception.MetadataNotFound: + metadata_ref = {} + role_ids = set(self._roles_from_role_dicts( + metadata_ref.get('roles', []), inherited_to_projects)) + if role_id not in role_ids: + raise exception.RoleNotFound(role_id=role_id) + return role_ref.to_dict() + + def delete_grant(self, role_id, user_id=None, group_id=None, + domain_id=None, project_id=None, + inherited_to_projects=False): + if user_id: + self.identity_api.get_user(user_id) + if group_id: + self.identity_api.get_group(group_id) + + session = self.get_session() + self._get_role(session, role_id) + + if domain_id: + self._get_domain(session, domain_id) + if project_id: + self._get_project(session, project_id) + + try: + metadata_ref = self._get_metadata(user_id, project_id, + domain_id, group_id) + is_new = False + except exception.MetadataNotFound: + metadata_ref = {} + is_new = True + + try: + metadata_ref['roles'] = self._remove_role_from_role_dicts( + role_id, inherited_to_projects, metadata_ref.get('roles', [])) + except KeyError: + raise exception.RoleNotFound(role_id=role_id) + + if is_new: + # TODO(henry-nash) It seems odd that you would create a new + # entry in response to trying to delete a role that was not + # assigned. Although benign, this should probably be removed. + self._create_metadata(user_id, project_id, metadata_ref, + domain_id, group_id) + else: + self._update_metadata(user_id, project_id, metadata_ref, + domain_id, group_id) + + def list_projects(self, domain_id=None): + session = self.get_session() + if domain_id: + self._get_domain(session, domain_id) + + query = session.query(Project) + if domain_id: + query = query.filter_by(domain_id=domain_id) + project_refs = query.all() + return [project_ref.to_dict() for project_ref in project_refs] + + def get_projects_for_user(self, user_id): + + # FIXME(henry-nash) The following should take into account + # both group and inherited roles. In fact, I don't see why this + # call can't be handled at the controller level like we do + # with 'get_roles_for_user_and_project()'. Further, this + # call seems essentially the same as 'list_user_projects()' + # later in this driver. Both should be removed. + + self.identity_api.get_user(user_id) + session = self.get_session() + query = session.query(UserProjectGrant) + query = query.filter_by(user_id=user_id) + membership_refs = query.all() + return [x.project_id for x in membership_refs] + + def add_role_to_user_and_project(self, user_id, tenant_id, role_id): + self.identity_api.get_user(user_id) + session = self.get_session() + self._get_project(session, tenant_id) + self._get_role(session, role_id) + try: + metadata_ref = self._get_metadata(user_id, tenant_id) + is_new = False + except exception.MetadataNotFound: + metadata_ref = {} + is_new = True + + try: + metadata_ref['roles'] = self._add_role_to_role_dicts( + role_id, False, metadata_ref.get('roles', []), + allow_existing=False) + except KeyError: + msg = ('User %s already has role %s in tenant %s' + % (user_id, role_id, tenant_id)) + raise exception.Conflict(type='role grant', details=msg) + + if is_new: + self._create_metadata(user_id, tenant_id, metadata_ref) + else: + self._update_metadata(user_id, tenant_id, metadata_ref) + + def remove_role_from_user_and_project(self, user_id, tenant_id, role_id): + try: + metadata_ref = self._get_metadata(user_id, tenant_id) + try: + metadata_ref['roles'] = self._remove_role_from_role_dicts( + role_id, False, metadata_ref.get('roles', [])) + except KeyError: + raise exception.RoleNotFound(message=_( + 'Cannot remove role that has not been granted, %s') % + role_id) + + if len(metadata_ref['roles']): + self._update_metadata(user_id, tenant_id, metadata_ref) + else: + session = self.get_session() + q = session.query(UserProjectGrant) + q = q.filter_by(user_id=user_id) + q = q.filter_by(project_id=tenant_id) + q.delete() + except exception.MetadataNotFound: + msg = 'Cannot remove role that has not been granted, %s' % role_id + raise exception.RoleNotFound(message=msg) + + def list_role_assignments(self): + + # TODO(henry-nash): The current implementation is really simulating + # us having a common role assignment table, rather than having the + # four different grant tables we have today. When we move to role + # assignment as a first class entity, we should create the single + # assignment table, simplifying the logic of this (and many other) + # functions. + + session = self.get_session() + assignment_list = [] + refs = session.query(UserDomainGrant).all() + for x in refs: + for r in self._roles_from_role_dicts( + x.data.get('roles', {}), False): + assignment_list.append({'user_id': x.user_id, + 'domain_id': x.domain_id, + 'role_id': r}) + for r in self._roles_from_role_dicts( + x.data.get('roles', {}), True): + assignment_list.append({'user_id': x.user_id, + 'domain_id': x.domain_id, + 'role_id': r, + 'inherited_to_projects': True}) + refs = session.query(UserProjectGrant).all() + for x in refs: + for r in self._roles_from_role_dicts( + x.data.get('roles', {}), False): + assignment_list.append({'user_id': x.user_id, + 'project_id': x.project_id, + 'role_id': r}) + refs = session.query(GroupDomainGrant).all() + for x in refs: + for r in self._roles_from_role_dicts( + x.data.get('roles', {}), False): + assignment_list.append({'group_id': x.group_id, + 'domain_id': x.domain_id, + 'role_id': r}) + for r in self._roles_from_role_dicts( + x.data.get('roles', {}), True): + assignment_list.append({'group_id': x.group_id, + 'domain_id': x.domain_id, + 'role_id': r, + 'inherited_to_projects': True}) + refs = session.query(GroupProjectGrant).all() + for x in refs: + for r in self._roles_from_role_dicts( + x.data.get('roles', {}), False): + assignment_list.append({'group_id': x.group_id, + 'project_id': x.project_id, + 'role_id': r}) + return assignment_list + + # CRUD + @sql.handle_conflicts(type='project') + def create_project(self, tenant_id, tenant): + tenant['name'] = clean.project_name(tenant['name']) + session = self.get_session() + with session.begin(): + tenant_ref = Project.from_dict(tenant) + session.add(tenant_ref) + session.flush() + return tenant_ref.to_dict() + + @sql.handle_conflicts(type='project') + def update_project(self, tenant_id, tenant): + session = self.get_session() + + if 'name' in tenant: + tenant['name'] = clean.project_name(tenant['name']) + + with session.begin(): + tenant_ref = self._get_project(session, tenant_id) + old_project_dict = tenant_ref.to_dict() + for k in tenant: + old_project_dict[k] = tenant[k] + new_project = Project.from_dict(old_project_dict) + for attr in Project.attributes: + if attr != 'id': + setattr(tenant_ref, attr, getattr(new_project, attr)) + tenant_ref.extra = new_project.extra + session.flush() + return tenant_ref.to_dict(include_extra_dict=True) + + @sql.handle_conflicts(type='project') + def delete_project(self, tenant_id): + session = self.get_session() + + with session.begin(): + tenant_ref = self._get_project(session, tenant_id) + + q = session.query(UserProjectGrant) + q = q.filter_by(project_id=tenant_id) + q.delete(False) + + q = session.query(UserProjectGrant) + q = q.filter_by(project_id=tenant_id) + q.delete(False) + + q = session.query(GroupProjectGrant) + q = q.filter_by(project_id=tenant_id) + q.delete(False) + + session.delete(tenant_ref) + session.flush() + + @sql.handle_conflicts(type='metadata') + def _create_metadata(self, user_id, tenant_id, metadata, + domain_id=None, group_id=None): + session = self.get_session() + with session.begin(): + if user_id: + if tenant_id: + session.add(UserProjectGrant + (user_id=user_id, + project_id=tenant_id, + data=metadata)) + elif domain_id: + session.add(UserDomainGrant + (user_id=user_id, + domain_id=domain_id, + data=metadata)) + elif group_id: + if tenant_id: + session.add(GroupProjectGrant + (group_id=group_id, + project_id=tenant_id, + data=metadata)) + elif domain_id: + session.add(GroupDomainGrant + (group_id=group_id, + domain_id=domain_id, + data=metadata)) + session.flush() + return metadata + + @sql.handle_conflicts(type='metadata') + def _update_metadata(self, user_id, tenant_id, metadata, + domain_id=None, group_id=None): + session = self.get_session() + with session.begin(): + if user_id: + if tenant_id: + q = session.query(UserProjectGrant) + q = q.filter_by(user_id=user_id) + q = q.filter_by(project_id=tenant_id) + elif domain_id: + q = session.query(UserDomainGrant) + q = q.filter_by(user_id=user_id) + q = q.filter_by(domain_id=domain_id) + elif group_id: + if tenant_id: + q = session.query(GroupProjectGrant) + q = q.filter_by(group_id=group_id) + q = q.filter_by(project_id=tenant_id) + elif domain_id: + q = session.query(GroupDomainGrant) + q = q.filter_by(group_id=group_id) + q = q.filter_by(domain_id=domain_id) + metadata_ref = q.first() + data = metadata_ref.data.copy() + data.update(metadata) + metadata_ref.data = data + session.flush() + return metadata_ref + + # domain crud + + @sql.handle_conflicts(type='domain') + def create_domain(self, domain_id, domain): + session = self.get_session() + with session.begin(): + ref = Domain.from_dict(domain) + session.add(ref) + session.flush() + return ref.to_dict() + + def list_domains(self): + session = self.get_session() + refs = session.query(Domain).all() + return [ref.to_dict() for ref in refs] + + def _get_domain(self, session, domain_id): + ref = session.query(Domain).get(domain_id) + if ref is None: + raise exception.DomainNotFound(domain_id=domain_id) + return ref + + def get_domain(self, domain_id): + session = self.get_session() + return self._get_domain(session, domain_id).to_dict() + + def get_domain_by_name(self, domain_name): + session = self.get_session() + try: + ref = (session.query(Domain). + filter_by(name=domain_name).one()) + except sql.NotFound: + raise exception.DomainNotFound(domain_id=domain_name) + return ref.to_dict() + + @sql.handle_conflicts(type='domain') + def update_domain(self, domain_id, domain): + session = self.get_session() + with session.begin(): + ref = self._get_domain(session, domain_id) + old_dict = ref.to_dict() + for k in domain: + old_dict[k] = domain[k] + new_domain = Domain.from_dict(old_dict) + for attr in Domain.attributes: + if attr != 'id': + setattr(ref, attr, getattr(new_domain, attr)) + ref.extra = new_domain.extra + session.flush() + return ref.to_dict() + + def delete_domain(self, domain_id): + session = self.get_session() + with session.begin(): + ref = self._get_domain(session, domain_id) + session.delete(ref) + session.flush() + + def list_user_projects(self, user_id): + + # FIXME(henry-nash) The following should take into account + # both group and inherited roles. In fact, I don't see why this + # call can't be handled at the controller level like we do + # with 'get_roles_for_user_and_project()'. Further, this + # call seems essentially the same as 'get_projects_for_user()' + # earlier in this driver. Both should be removed. + + session = self.get_session() + user = self.identity_api.get_user(user_id) + metadata_refs = session\ + .query(UserProjectGrant)\ + .filter_by(user_id=user_id) + project_ids = set([x.project_id for x in metadata_refs + if x.data.get('roles')]) + if user.get('project_id'): + project_ids.add(user['project_id']) + + # FIXME(dolph): this should be removed with proper migrations + if user.get('tenant_id'): + project_ids.add(user['tenant_id']) + + return [self.get_project(x) for x in project_ids] + + # role crud + + @sql.handle_conflicts(type='role') + def create_role(self, role_id, role): + session = self.get_session() + with session.begin(): + ref = Role.from_dict(role) + session.add(ref) + session.flush() + return ref.to_dict() + + def list_roles(self): + session = self.get_session() + refs = session.query(Role).all() + return [ref.to_dict() for ref in refs] + + def _get_role(self, session, role_id): + ref = session.query(Role).get(role_id) + if ref is None: + raise exception.RoleNotFound(role_id=role_id) + return ref + + def get_role(self, role_id): + session = self.get_session() + return self._get_role(session, role_id).to_dict() + + @sql.handle_conflicts(type='role') + def update_role(self, role_id, role): + session = self.get_session() + with session.begin(): + ref = self._get_role(session, role_id) + old_dict = ref.to_dict() + for k in role: + old_dict[k] = role[k] + new_role = Role.from_dict(old_dict) + for attr in Role.attributes: + if attr != 'id': + setattr(ref, attr, getattr(new_role, attr)) + ref.extra = new_role.extra + session.flush() + return ref.to_dict() + + def delete_role(self, role_id): + session = self.get_session() + + with session.begin(): + ref = self._get_role(session, role_id) + for metadata_ref in session.query(UserProjectGrant): + try: + self.delete_grant(role_id, user_id=metadata_ref.user_id, + project_id=metadata_ref.project_id) + except exception.RoleNotFound: + pass + for metadata_ref in session.query(UserDomainGrant): + try: + self.delete_grant(role_id, user_id=metadata_ref.user_id, + domain_id=metadata_ref.domain_id) + except exception.RoleNotFound: + pass + for metadata_ref in session.query(GroupProjectGrant): + try: + self.delete_grant(role_id, group_id=metadata_ref.group_id, + project_id=metadata_ref.project_id) + except exception.RoleNotFound: + pass + for metadata_ref in session.query(GroupDomainGrant): + try: + self.delete_grant(role_id, group_id=metadata_ref.group_id, + domain_id=metadata_ref.domain_id) + except exception.RoleNotFound: + pass + + session.delete(ref) + session.flush() + + def delete_user(self, user_id): + session = self.get_session() + + with session.begin(): + q = session.query(UserProjectGrant) + q = q.filter_by(user_id=user_id) + q.delete(False) + + q = session.query(UserDomainGrant) + q = q.filter_by(user_id=user_id) + q.delete(False) + + session.flush() + + def delete_group(self, group_id): + session = self.get_session() + + with session.begin(): + + q = session.query(GroupProjectGrant) + q = q.filter_by(group_id=group_id) + q.delete(False) + + q = session.query(GroupDomainGrant) + q = q.filter_by(group_id=group_id) + q.delete(False) + + session.flush() + + +class Domain(sql.ModelBase, sql.DictBase): + __tablename__ = 'domain' + attributes = ['id', 'name', 'enabled'] + id = sql.Column(sql.String(64), primary_key=True) + name = sql.Column(sql.String(64), nullable=False) + enabled = sql.Column(sql.Boolean, default=True, nullable=False) + extra = sql.Column(sql.JsonBlob()) + __table_args__ = (sql.UniqueConstraint('name'), {}) + + +class Project(sql.ModelBase, sql.DictBase): + __tablename__ = 'project' + attributes = ['id', 'name', 'domain_id', 'description', 'enabled'] + id = sql.Column(sql.String(64), primary_key=True) + name = sql.Column(sql.String(64), nullable=False) + domain_id = sql.Column(sql.String(64), sql.ForeignKey('domain.id'), + nullable=False) + description = sql.Column(sql.Text()) + enabled = sql.Column(sql.Boolean) + extra = sql.Column(sql.JsonBlob()) + # Unique constraint across two columns to create the separation + # rather than just only 'name' being unique + __table_args__ = (sql.UniqueConstraint('domain_id', 'name'), {}) + + +class Role(sql.ModelBase, sql.DictBase): + __tablename__ = 'role' + attributes = ['id', 'name'] + id = sql.Column(sql.String(64), primary_key=True) + name = sql.Column(sql.String(255), nullable=False) + extra = sql.Column(sql.JsonBlob()) + __table_args__ = (sql.UniqueConstraint('name'), {}) + + +class BaseGrant(sql.DictBase): + """Base Grant class. + + There are four grant tables in the current implementation, one for + each type of grant: + + - User for Project + - User for Domain + - Group for Project + - Group for Domain + + Each is a table with the two attributes above as a combined primary key, + with the data field holding all roles for that combination. The data + field is a list of dicts. For regular role assignments each dict in + the list of of the form: + + {'id': role_id} + + If the OS-INHERIT extension is enabled and the role on a domain is an + inherited role, the dict will be of the form: + + {'id': role_id, 'inherited_to': 'projects'} + + """ + def to_dict(self): + """Override parent to_dict() method with a simpler implementation. + + Grant tables don't have non-indexed 'extra' attributes, so the + parent implementation is not applicable. + """ + return dict(self.iteritems()) + + +class UserProjectGrant(sql.ModelBase, BaseGrant): + __tablename__ = 'user_project_metadata' + user_id = sql.Column(sql.String(64), primary_key=True) + project_id = sql.Column(sql.String(64), sql.ForeignKey('project.id'), + primary_key=True) + data = sql.Column(sql.JsonBlob()) + + +class UserDomainGrant(sql.ModelBase, BaseGrant): + __tablename__ = 'user_domain_metadata' + user_id = sql.Column(sql.String(64), primary_key=True) + domain_id = sql.Column(sql.String(64), sql.ForeignKey('domain.id'), + primary_key=True) + data = sql.Column(sql.JsonBlob()) + + +class GroupProjectGrant(sql.ModelBase, BaseGrant): + __tablename__ = 'group_project_metadata' + group_id = sql.Column(sql.String(64), primary_key=True) + project_id = sql.Column(sql.String(64), sql.ForeignKey('project.id'), + primary_key=True) + data = sql.Column(sql.JsonBlob()) + + +class GroupDomainGrant(sql.ModelBase, BaseGrant): + __tablename__ = 'group_domain_metadata' + group_id = sql.Column(sql.String(64), primary_key=True) + domain_id = sql.Column(sql.String(64), sql.ForeignKey('domain.id'), + primary_key=True) + data = sql.Column(sql.JsonBlob()) diff --git a/keystone/assignment/core.py b/keystone/assignment/core.py new file mode 100644 index 00000000..64edb3fa --- /dev/null +++ b/keystone/assignment/core.py @@ -0,0 +1,548 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2012 OpenStack LLC +# +# 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. + +"""Main entry point into the assignment service.""" + +from keystone.common import dependency +from keystone.common import logging +from keystone.common import manager +from keystone import config +from keystone import exception + + +CONF = config.CONF +LOG = logging.getLogger(__name__) + +DEFAULT_DOMAIN = {'description': + (u'Owns users and tenants (i.e. projects)' + ' available on Identity API v2.'), + 'enabled': True, + 'id': CONF.identity.default_domain_id, + 'name': u'Default'} + + +@dependency.provider('assignment_api') +@dependency.requires('identity_api') +class Manager(manager.Manager): + """Default pivot point for the Assignment backend. + + See :mod:`keystone.common.manager.Manager` for more details on how this + dynamically calls the backend. + assignment.Manager() and identity.Manager() have a circular dependency. + The late import works around this. THe if block prevents creation of the + api object by both managers. + """ + + def __init__(self): + assignment_driver = CONF.assignment.driver + + if assignment_driver is None: + identity_driver = dependency.REGISTRY['identity_api'].driver + assignment_driver = identity_driver.default_assignment_driver() + + super(Manager, self).__init__(assignment_driver) + + def get_roles_for_user_and_project(self, user_id, tenant_id): + """Get the roles associated with a user within given project. + + This includes roles directly assigned to the user on the + project, as well as those by virtue of group membership. If + the OS-INHERIT extension is enabled, then this will also + include roles inherited from the domain. + + :returns: a list of role ids. + :raises: keystone.exception.UserNotFound, + keystone.exception.ProjectNotFound + + """ + def _get_group_project_roles(user_id, project_ref): + role_list = [] + group_refs = (self.identity_api.list_groups_for_user + (user_id=user_id)) + for x in group_refs: + try: + metadata_ref = self._get_metadata( + group_id=x['id'], tenant_id=project_ref['id']) + role_list += self._roles_from_role_dicts( + metadata_ref.get('roles', {}), False) + except exception.MetadataNotFound: + # no group grant, skip + pass + + if CONF.os_inherit.enabled: + # Now get any inherited group roles for the owning domain + try: + metadata_ref = self._get_metadata( + group_id=x['id'], + domain_id=project_ref['domain_id']) + role_list += self._roles_from_role_dicts( + metadata_ref.get('roles', {}), True) + except (exception.MetadataNotFound, + exception.NotImplemented): + pass + + return role_list + + def _get_user_project_roles(user_id, project_ref): + role_list = [] + try: + metadata_ref = self._get_metadata(user_id=user_id, + tenant_id=project_ref['id']) + role_list = self._roles_from_role_dicts( + metadata_ref.get('roles', {}), False) + except exception.MetadataNotFound: + pass + + if CONF.os_inherit.enabled: + # Now get any inherited roles for the owning domain + try: + metadata_ref = self._get_metadata( + user_id=user_id, domain_id=project_ref['domain_id']) + role_list += self._roles_from_role_dicts( + metadata_ref.get('roles', {}), True) + except (exception.MetadataNotFound, exception.NotImplemented): + pass + + return role_list + + self.identity_api.get_user(user_id) + project_ref = self.get_project(tenant_id) + user_role_list = _get_user_project_roles(user_id, project_ref) + group_role_list = _get_group_project_roles(user_id, project_ref) + # Use set() to process the list to remove any duplicates + return list(set(user_role_list + group_role_list)) + + def get_roles_for_user_and_domain(self, user_id, domain_id): + """Get the roles associated with a user within given domain. + + :returns: a list of role ids. + :raises: keystone.exception.UserNotFound, + keystone.exception.DomainNotFound + + """ + + def _get_group_domain_roles(user_id, domain_id): + role_list = [] + group_refs = (self.identity_api. + list_groups_for_user(user_id=user_id)) + for x in group_refs: + try: + metadata_ref = self._get_metadata(group_id=x['id'], + domain_id=domain_id) + role_list += self._roles_from_role_dicts( + metadata_ref.get('roles', {}), False) + except (exception.MetadataNotFound, exception.NotImplemented): + # MetadataNotFound implies no group grant, so skip. + # Ignore NotImplemented since not all backends support + # domains. + pass + return role_list + + def _get_user_domain_roles(user_id, domain_id): + metadata_ref = {} + try: + metadata_ref = self._get_metadata(user_id=user_id, + domain_id=domain_id) + except (exception.MetadataNotFound, exception.NotImplemented): + # MetadataNotFound implies no user grants. + # Ignore NotImplemented since not all backends support + # domains + pass + return self._roles_from_role_dicts( + metadata_ref.get('roles', {}), False) + + self.identity_api.get_user(user_id) + self.get_domain(domain_id) + user_role_list = _get_user_domain_roles(user_id, domain_id) + group_role_list = _get_group_domain_roles(user_id, domain_id) + # Use set() to process the list to remove any duplicates + return list(set(user_role_list + group_role_list)) + + def add_user_to_project(self, tenant_id, user_id): + """Add user to a tenant by creating a default role relationship. + + :raises: keystone.exception.ProjectNotFound, + keystone.exception.UserNotFound + + """ + self.driver.add_role_to_user_and_project(user_id, + tenant_id, + config.CONF.member_role_id) + + def remove_user_from_project(self, tenant_id, user_id): + """Remove user from a tenant + + :raises: keystone.exception.ProjectNotFound, + keystone.exception.UserNotFound + + """ + roles = self.get_roles_for_user_and_project(user_id, tenant_id) + if not roles: + raise exception.NotFound(tenant_id) + for role_id in roles: + self.remove_role_from_user_and_project(user_id, tenant_id, role_id) + + +class Driver(object): + + def _role_to_dict(self, role_id, inherited): + role_dict = {'id': role_id} + if inherited: + role_dict['inherited_to'] = 'projects' + return role_dict + + def _roles_from_role_dicts(self, dict_list, inherited): + role_list = [] + for d in dict_list: + if ((not d.get('inherited_to') and not inherited) or + (d.get('inherited_to') == 'projects' and inherited)): + role_list.append(d['id']) + return role_list + + def _add_role_to_role_dicts(self, role_id, inherited, dict_list, + allow_existing=True): + # There is a difference in error semantics when trying to + # assign a role that already exists between the coded v2 and v3 + # API calls. v2 will error if the assignment already exists, + # while v3 is silent. Setting the 'allow_existing' parameter + # appropriately lets this call be used for both. + role_set = set([frozenset(r.items()) for r in dict_list]) + key = frozenset(self._role_to_dict(role_id, inherited).items()) + if not allow_existing and key in role_set: + raise KeyError + role_set.add(key) + return [dict(r) for r in role_set] + + def _remove_role_from_role_dicts(self, role_id, inherited, dict_list): + role_set = set([frozenset(r.items()) for r in dict_list]) + role_set.remove(frozenset(self._role_to_dict(role_id, + inherited).items())) + return [dict(r) for r in role_set] + + def get_project_by_name(self, tenant_name, domain_id): + """Get a tenant by name. + + :returns: tenant_ref + :raises: keystone.exception.ProjectNotFound + + """ + raise exception.NotImplemented() + + def get_project_users(self, tenant_id): + """Lists all users with a relationship to the specified project. + + :returns: a list of user_refs or an empty set. + :raises: keystone.exception.ProjectNotFound + + """ + raise exception.NotImplemented() + + def get_projects_for_user(self, user_id): + """Get the tenants associated with a given user. + + :returns: a list of tenant_id's. + :raises: keystone.exception.UserNotFound + + """ + raise exception.NotImplemented() + + def add_role_to_user_and_project(self, user_id, tenant_id, role_id): + """Add a role to a user within given tenant. + + :raises: keystone.exception.UserNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.RoleNotFound + """ + raise exception.NotImplemented() + + def remove_role_from_user_and_project(self, user_id, tenant_id, role_id): + """Remove a role from a user within given tenant. + + :raises: keystone.exception.UserNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.RoleNotFound + + """ + raise exception.NotImplemented() + + # assignment/grant crud + + def create_grant(self, role_id, user_id=None, group_id=None, + domain_id=None, project_id=None, + inherited_to_projects=False): + """Creates a new assignment/grant. + + If the assignment is to a domain, then optionally it may be + specified as inherited to owned projects (this requires + the OS-INHERIT extension to be enabled). + + :raises: keystone.exception.UserNotFound, + keystone.exception.GroupNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.DomainNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.RoleNotFound + + """ + raise exception.NotImplemented() + + def list_grants(self, user_id=None, group_id=None, + domain_id=None, project_id=None, + inherited_to_projects=False): + """Lists assignments/grants. + + :raises: keystone.exception.UserNotFound, + keystone.exception.GroupNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.DomainNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.RoleNotFound + + """ + raise exception.NotImplemented() + + def get_grant(self, role_id, user_id=None, group_id=None, + domain_id=None, project_id=None, + inherited_to_projects=False): + """Lists assignments/grants. + + :raises: keystone.exception.UserNotFound, + keystone.exception.GroupNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.DomainNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.RoleNotFound + + """ + raise exception.NotImplemented() + + def delete_grant(self, role_id, user_id=None, group_id=None, + domain_id=None, project_id=None, + inherited_to_projects=False): + """Lists assignments/grants. + + :raises: keystone.exception.UserNotFound, + keystone.exception.GroupNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.DomainNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.RoleNotFound + + """ + raise exception.NotImplemented() + + def list_role_assignments(self): + + raise exception.NotImplemented() + + # domain crud + def create_domain(self, domain_id, domain): + """Creates a new domain. + + :raises: keystone.exception.Conflict + + """ + raise exception.NotImplemented() + + def list_domains(self): + """List all domains in the system. + + :returns: a list of domain_refs or an empty list. + + """ + raise exception.NotImplemented() + + def get_domain(self, domain_id): + """Get a domain by ID. + + :returns: domain_ref + :raises: keystone.exception.DomainNotFound + + """ + raise exception.NotImplemented() + + def get_domain_by_name(self, domain_name): + """Get a domain by name. + + :returns: domain_ref + :raises: keystone.exception.DomainNotFound + + """ + raise exception.NotImplemented() + + def update_domain(self, domain_id, domain): + """Updates an existing domain. + + :raises: keystone.exception.DomainNotFound, + keystone.exception.Conflict + + """ + raise exception.NotImplemented() + + def delete_domain(self, domain_id): + """Deletes an existing domain. + + :raises: keystone.exception.DomainNotFound + + """ + raise exception.NotImplemented() + + # project crud + def create_project(self, project_id, project): + """Creates a new project. + + :raises: keystone.exception.Conflict + + """ + raise exception.NotImplemented() + + def list_projects(self, domain_id=None): + """List all projects in the system. + + :returns: a list of project_refs or an empty list. + + """ + raise exception.NotImplemented() + + def list_user_projects(self, user_id): + """List all projects associated with a given user. + + :returns: a list of project_refs or an empty list. + + """ + raise exception.NotImplemented() + + def get_project(self, project_id): + """Get a project by ID. + + :returns: project_ref + :raises: keystone.exception.ProjectNotFound + + """ + raise exception.NotImplemented() + + def update_project(self, project_id, project): + """Updates an existing project. + + :raises: keystone.exception.ProjectNotFound, + keystone.exception.Conflict + + """ + raise exception.NotImplemented() + + def delete_project(self, project_id): + """Deletes an existing project. + + :raises: keystone.exception.ProjectNotFound + + """ + raise exception.NotImplemented() + + """Interface description for an assignment driver.""" + # role crud + + def create_role(self, role_id, role): + """Creates a new role. + + :raises: keystone.exception.Conflict + + """ + raise exception.NotImplemented() + + def list_roles(self): + """List all roles in the system. + + :returns: a list of role_refs or an empty list. + + """ + raise exception.NotImplemented() + + def get_role(self, role_id): + """Get a role by ID. + + :returns: role_ref + :raises: keystone.exception.RoleNotFound + + """ + raise exception.NotImplemented() + + def update_role(self, role_id, role): + """Updates an existing role. + + :raises: keystone.exception.RoleNotFound, + keystone.exception.Conflict + + """ + raise exception.NotImplemented() + + def delete_role(self, role_id): + """Deletes an existing role. + + :raises: keystone.exception.RoleNotFound + + """ + raise exception.NotImplemented() + +#TODO(ayoung): determine what else these two functions raise + def delete_user(self, user_id): + """Deletes all assignments for a user. + + :raises: keystone.exception.RoleNotFound + + """ + raise exception.NotImplemented() + + def delete_group(self, group_id): + """Deletes all assignments for a group. + + :raises: keystone.exception.RoleNotFound + + """ + raise exception.NotImplemented() + + #domain management functions for backends that only allow a single domain. + #currently, this is only LDAP, but might be used by PAM or other backends + #as well. This is used by both identity and assignment drivers. + def _set_default_domain(self, ref): + """If the domain ID has not been set, set it to the default.""" + if isinstance(ref, dict): + if 'domain_id' not in ref: + ref = ref.copy() + ref['domain_id'] = CONF.identity.default_domain_id + return ref + elif isinstance(ref, list): + return [self._set_default_domain(x) for x in ref] + else: + raise ValueError(_('Expected dict or list: %s') % type(ref)) + + def _validate_default_domain(self, ref): + """Validate that either the default domain or nothing is specified. + + Also removes the domain from the ref so that LDAP doesn't have to + persist the attribute. + + """ + ref = ref.copy() + domain_id = ref.pop('domain_id', CONF.identity.default_domain_id) + self._validate_default_domain_id(domain_id) + return ref + + def _validate_default_domain_id(self, domain_id): + """Validate that the domain ID specified belongs to the default domain. + + """ + if domain_id != CONF.identity.default_domain_id: + raise exception.DomainNotFound(domain_id=domain_id) diff --git a/keystone/auth/controllers.py b/keystone/auth/controllers.py index bef4128d..d1bd764f 100644 --- a/keystone/auth/controllers.py +++ b/keystone/auth/controllers.py @@ -14,12 +14,11 @@ # License for the specific language governing permissions and limitations # under the License. -import json -from keystone.auth import token_factory -from keystone.common import cms from keystone.common import controller +from keystone.common import dependency from keystone.common import logging +from keystone.common import wsgi from keystone import config from keystone import exception from keystone import identity @@ -190,6 +189,10 @@ class AuthInfo(object): self._scope_data = (None, None, trust_ref) def _validate_auth_methods(self): + if 'identity' not in self.auth: + raise exception.ValidationError(attribute='identity', + target='auth') + # make sure auth methods are provided if 'methods' not in self.auth['identity']: raise exception.ValidationError(attribute='methods', @@ -222,7 +225,7 @@ class AuthInfo(object): :returns: list of auth method names """ - return self.auth['identity']['methods'] + return self.auth['identity']['methods'] or [] def get_method_data(self, method): """Get the auth method payload. @@ -267,6 +270,7 @@ class AuthInfo(object): self._scope_data = (domain_id, project_id, trust) +@dependency.requires('token_provider_api') class Auth(controller.V3Controller): def __init__(self, *args, **kw): super(Auth, self).__init__(*args, **kw) @@ -275,19 +279,31 @@ class Auth(controller.V3Controller): def authenticate_for_token(self, context, auth=None): """Authenticate user and issue a token.""" + include_catalog = 'nocatalog' not in context['query_string'] + try: auth_info = AuthInfo(context, auth=auth) - auth_context = {'extras': {}, 'method_names': []} + auth_context = {'extras': {}, 'method_names': [], 'bind': {}} self.authenticate(context, auth_info, auth_context) self._check_and_set_default_scoping(auth_info, auth_context) - (token_id, token_data) = token_factory.create_token( - auth_context, auth_info) - return token_factory.render_token_data_response( - token_id, token_data, created=True) - except exception.SecurityError: - raise - except Exception as e: - LOG.exception(e) + (domain_id, project_id, trust) = auth_info.get_scope() + method_names = auth_info.get_method_names() + method_names += auth_context.get('method_names', []) + # make sure the list is unique + method_names = list(set(method_names)) + + (token_id, token_data) = self.token_provider_api.issue_token( + user_id=auth_context['user_id'], + method_names=method_names, + expires_at=auth_context.get('expires_at'), + project_id=project_id, + domain_id=domain_id, + auth_context=auth_context, + trust=trust, + include_catalog=include_catalog) + return render_token_data_response(token_id, token_data, + created=True) + except exception.TrustNotFound as e: raise exception.Unauthorized(e) def _check_and_set_default_scoping(self, auth_info, auth_context): @@ -309,31 +325,13 @@ class Auth(controller.V3Controller): LOG.exception(e) raise exception.Unauthorized(e) - def _build_remote_user_auth_context(self, context, auth_info, - auth_context): - username = context['REMOTE_USER'] - # FIXME(gyee): REMOTE_USER is not good enough since we are - # requiring domain_id to do user lookup now. Try to get - # the user_id from auth_info for now, assuming external auth - # has check to make sure user is the same as the one specify - # in "identity". - if 'password' in auth_info.get_method_names(): - user_info = auth_info.get_method_data('password') - user_ref = auth_info.lookup_user(user_info['user']) - auth_context['user_id'] = user_ref['id'] - else: - msg = _('Unable to lookup user %s') % (username) - raise exception.Unauthorized(msg) - def authenticate(self, context, auth_info, auth_context): """Authenticate user.""" # user have been authenticated externally if 'REMOTE_USER' in context: - self._build_remote_user_auth_context(context, - auth_info, - auth_context) - return + external = get_auth_method('external') + external.authenticate(context, auth_info, auth_context) # need to aggregate the results in case two or more methods # are specified @@ -355,44 +353,41 @@ class Auth(controller.V3Controller): msg = _('User not found') raise exception.Unauthorized(msg) - def _get_token_ref(self, context, token_id, belongs_to=None): - token_ref = self.token_api.get_token(token_id) - if cms.is_ans1_token(token_id): - verified_token = cms.cms_verify(cms.token_to_cms(token_id), - CONF.signing.certfile, - CONF.signing.ca_certs) - token_ref = json.loads(verified_token) - if belongs_to: - assert token_ref['project']['id'] == belongs_to - return token_ref - @controller.protected def check_token(self, context): - try: - token_id = context.get('subject_token_id') - belongs_to = context['query_string'].get('belongsTo') - assert self._get_token_ref(context, token_id, belongs_to) - except Exception as e: - LOG.error(e) - raise exception.Unauthorized(e) + token_id = context.get('subject_token_id') + self.token_provider_api.check_token(token_id) @controller.protected def revoke_token(self, context): token_id = context.get('subject_token_id') - return self.token_controllers_ref.delete_token(context, token_id) + return self.token_provider_api.revoke_token(token_id) @controller.protected def validate_token(self, context): token_id = context.get('subject_token_id') - self.check_token(context) - token_ref = self.token_api.get_token(token_id) - token_data = token_factory.recreate_token_data( - token_ref.get('token_data'), - token_ref['expires'], - token_ref.get('user'), - token_ref.get('tenant')) - return token_factory.render_token_data_response(token_id, token_data) + token_data = self.token_provider_api.validate_token(token_id) + return render_token_data_response(token_id, token_data) @controller.protected def revocation_list(self, context, auth=None): return self.token_controllers_ref.revocation_list(context, auth) + + +#FIXME(gyee): not sure if it belongs here or keystone.common. Park it here +# for now. +def render_token_data_response(token_id, token_data, created=False): + """Render token data HTTP response. + + Stash token ID into the X-Subject-Token header. + + """ + headers = [('X-Subject-Token', token_id)] + + if created: + status = (201, 'Created') + else: + status = (200, 'OK') + + return wsgi.render_response(body=token_data, + status=status, headers=headers) diff --git a/keystone/auth/plugins/external.py b/keystone/auth/plugins/external.py new file mode 100644 index 00000000..67b11001 --- /dev/null +++ b/keystone/auth/plugins/external.py @@ -0,0 +1,87 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 OpenStack LLC +# +# 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. + +"""Keystone External Authentication Plugin""" + +from keystone.common import config +from keystone import exception + + +CONF = config.CONF + + +class ExternalDefault(object): + def authenticate(self, context, auth_info, auth_context): + """Use REMOTE_USER to look up the user in the identity backend + + auth_context is an in-out variable that will be updated with the + username from the REMOTE_USER environment variable. + """ + try: + REMOTE_USER = context['REMOTE_USER'] + except KeyError: + msg = _('No authenticated user') + raise exception.Unauthorized(msg) + try: + names = REMOTE_USER.split('@') + username = names.pop(0) + domain_id = CONF.identity.default_domain_id + user_ref = auth_info.identity_api.get_user_by_name(username, + domain_id) + auth_context['user_id'] = user_ref['id'] + if ('kerberos' in CONF.token.bind and + context.get('AUTH_TYPE', '').lower() == 'negotiate'): + auth_context['bind']['kerberos'] = username + except Exception: + msg = _('Unable to lookup user %s') % (REMOTE_USER) + raise exception.Unauthorized(msg) + + +class ExternalDomain(object): + def authenticate(self, context, auth_info, auth_context): + """Use REMOTE_USER to look up the user in the identity backend + + auth_context is an in-out variable that will be updated with the + username from the REMOTE_USER environment variable. + + If REMOTE_USER contains an `@` assume that the substring before the @ + is the username, and the substring after the @ is the domain name. + """ + try: + REMOTE_USER = context['REMOTE_USER'] + except KeyError: + msg = _('No authenticated user') + raise exception.Unauthorized(msg) + try: + names = REMOTE_USER.split('@') + username = names.pop(0) + if names: + domain_name = names[0] + domain_ref = (auth_info.identity_api. + get_domain_by_name(domain_name)) + domain_id = domain_ref['id'] + else: + domain_id = CONF.identity.default_domain_id + user_ref = auth_info.identity_api.get_user_by_name(username, + domain_id) + auth_context['user_id'] = user_ref['id'] + if ('kerberos' in CONF.token.bind and + context.get('AUTH_TYPE', '').lower() == 'negotiate'): + auth_context['bind']['kerberos'] = username + + except Exception: + msg = _('Unable to lookup user %s') % (REMOTE_USER) + raise exception.Unauthorized(msg) diff --git a/keystone/auth/plugins/password.py b/keystone/auth/plugins/password.py index 631ce08d..f3cfeba8 100644 --- a/keystone/auth/plugins/password.py +++ b/keystone/auth/plugins/password.py @@ -103,8 +103,14 @@ class Password(auth.AuthMethodHandler): # FIXME(gyee): identity.authenticate() can use some refactoring since # all we care is password matches - self.identity_api.authenticate( - user_id=user_info.user_id, - password=user_info.password) + try: + self.identity_api.authenticate( + user_id=user_info.user_id, + password=user_info.password) + except AssertionError: + # authentication failed because of invalid username or password + msg = _('Invalid username or password') + raise exception.Unauthorized(msg) + if 'user_id' not in user_context: user_context['user_id'] = user_info.user_id diff --git a/keystone/auth/plugins/token.py b/keystone/auth/plugins/token.py index d9b3d2f8..720eccac 100644 --- a/keystone/auth/plugins/token.py +++ b/keystone/auth/plugins/token.py @@ -16,6 +16,7 @@ from keystone import auth from keystone.common import logging +from keystone.common import wsgi from keystone import exception from keystone import token @@ -36,6 +37,7 @@ class Token(auth.AuthMethodHandler): target=METHOD_NAME) token_id = auth_payload['id'] token_ref = self.token_api.get_token(token_id) + wsgi.validate_token_bind(context, token_ref) user_context.setdefault( 'user_id', token_ref['token_data']['token']['user']['id']) # to support Grizzly-3 to Grizzly-RC1 transition @@ -46,7 +48,8 @@ class Token(auth.AuthMethodHandler): token_ref['token_data']['token']['extras']) user_context['method_names'].extend( token_ref['token_data']['token']['methods']) - if 'trust' in token_ref['token_data']: + if ('OS-TRUST:trust' in token_ref['token_data']['token'] or + 'trust' in token_ref['token_data']['token']): raise exception.Forbidden() except AssertionError as e: LOG.error(e) diff --git a/keystone/auth/token_factory.py b/keystone/auth/token_factory.py deleted file mode 100644 index 22bc8363..00000000 --- a/keystone/auth/token_factory.py +++ /dev/null @@ -1,368 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2013 OpenStack LLC -# -# 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. - -"""Token Factory""" - -import json -import sys -import uuid -import webob - -from keystone import catalog -from keystone.common import cms -from keystone.common import environment -from keystone.common import logging -from keystone.common import utils -from keystone import config -from keystone import exception -from keystone import identity -from keystone.openstack.common import jsonutils -from keystone.openstack.common import timeutils -from keystone import token as token_module -from keystone import trust - - -CONF = config.CONF - -LOG = logging.getLogger(__name__) - - -class TokenDataHelper(object): - """Token data helper.""" - def __init__(self): - self.identity_api = identity.Manager() - self.catalog_api = catalog.Manager() - self.trust_api = trust.Manager() - - def _get_filtered_domain(self, domain_id): - domain_ref = self.identity_api.get_domain(domain_id) - return {'id': domain_ref['id'], 'name': domain_ref['name']} - - def _populate_scope(self, token_data, domain_id, project_id): - if 'domain' in token_data or 'project' in token_data: - return - - if domain_id: - token_data['domain'] = self._get_filtered_domain(domain_id) - if project_id: - project_ref = self.identity_api.get_project(project_id) - filtered_project = { - 'id': project_ref['id'], - 'name': project_ref['name']} - filtered_project['domain'] = self._get_filtered_domain( - project_ref['domain_id']) - token_data['project'] = filtered_project - - def _get_project_roles_for_user(self, user_id, project_id): - roles = self.identity_api.get_roles_for_user_and_project( - user_id, project_id) - roles_ref = [] - for role_id in roles: - role_ref = self.identity_api.get_role(role_id) - role_ref.setdefault('project_id', project_id) - roles_ref.append(role_ref) - # user have no project roles, therefore access denied - if len(roles_ref) == 0: - msg = _('User have no access to project') - LOG.debug(msg) - raise exception.Unauthorized(msg) - return roles_ref - - def _get_domain_roles_for_user(self, user_id, domain_id): - roles = self.identity_api.get_roles_for_user_and_domain( - user_id, domain_id) - roles_ref = [] - for role_id in roles: - role_ref = self.identity_api.get_role(role_id) - role_ref.setdefault('domain_id', domain_id) - roles_ref.append(role_ref) - # user have no domain roles, therefore access denied - if len(roles_ref) == 0: - msg = _('User have no access to domain') - LOG.debug(msg) - raise exception.Unauthorized(msg) - return roles_ref - - def _get_roles_for_user(self, user_id, domain_id, project_id): - roles = [] - if domain_id: - roles = self._get_domain_roles_for_user(user_id, domain_id) - if project_id: - roles = self._get_project_roles_for_user(user_id, project_id) - return roles - - def _populate_user(self, token_data, user_id, domain_id, project_id, - trust): - if 'user' in token_data: - return - - user_ref = self.identity_api.get_user(user_id) - if CONF.trust.enabled and trust: - trustor_user_ref = self.identity_api.get_user( - trust['trustor_user_id']) - if not trustor_user_ref['enabled']: - raise exception.Forbidden() - if trust['impersonation']: - user_ref = trustor_user_ref - token_data['OS-TRUST:trust'] = ( - { - 'id': trust['id'], - 'trustor_user': {'id': trust['trustor_user_id']}, - 'trustee_user': {'id': trust['trustee_user_id']}, - 'impersonation': trust['impersonation'] - }) - filtered_user = { - 'id': user_ref['id'], - 'name': user_ref['name'], - 'domain': self._get_filtered_domain(user_ref['domain_id'])} - token_data['user'] = filtered_user - - def _populate_roles(self, token_data, user_id, domain_id, project_id, - trust): - if 'roles' in token_data: - return - - if CONF.trust.enabled and trust: - token_user_id = trust['trustor_user_id'] - token_project_id = trust['project_id'] - #trusts do not support domains yet - token_domain_id = None - else: - token_user_id = user_id - token_project_id = project_id - token_domain_id = domain_id - - if token_domain_id or token_project_id: - roles = self._get_roles_for_user(token_user_id, - token_domain_id, - token_project_id) - filtered_roles = [] - if CONF.trust.enabled and trust: - for trust_role in trust['roles']: - match_roles = [x for x in roles - if x['id'] == trust_role['id']] - if match_roles: - filtered_roles.append(match_roles[0]) - else: - raise exception.Forbidden() - else: - for role in roles: - filtered_roles.append({'id': role['id'], - 'name': role['name']}) - token_data['roles'] = filtered_roles - - def _populate_service_catalog(self, token_data, user_id, - domain_id, project_id, trust): - if 'catalog' in token_data: - return - - if CONF.trust.enabled and trust: - user_id = trust['trustor_user_id'] - if project_id or domain_id: - try: - service_catalog = self.catalog_api.get_v3_catalog( - user_id, project_id) - # TODO(ayoung): KVS backend needs a sample implementation - except exception.NotImplemented: - service_catalog = {} - # TODO(gyee): v3 service catalog is not quite completed yet - # TODO(ayoung): Enforce Endpoints for trust - token_data['catalog'] = service_catalog - - def _populate_token(self, token_data, expires=None, trust=None): - if not expires: - expires = token_module.default_expire_time() - if not isinstance(expires, basestring): - expires = timeutils.isotime(expires, subsecond=True) - token_data['expires_at'] = expires - token_data['issued_at'] = timeutils.isotime(subsecond=True) - - def get_token_data(self, user_id, method_names, extras, - domain_id=None, project_id=None, expires=None, - trust=None, token=None): - token_data = {'methods': method_names, - 'extras': extras} - - # We've probably already written these to the token - for x in ('roles', 'user', 'catalog', 'project', 'domain'): - if token and x in token: - token_data[x] = token[x] - - if CONF.trust.enabled and trust: - if user_id != trust['trustee_user_id']: - raise exception.Forbidden() - - self._populate_scope(token_data, domain_id, project_id) - self._populate_user(token_data, user_id, domain_id, project_id, trust) - self._populate_roles(token_data, user_id, domain_id, project_id, trust) - self._populate_service_catalog(token_data, user_id, domain_id, - project_id, trust) - self._populate_token(token_data, expires, trust) - return {'token': token_data} - - -def recreate_token_data(token_data=None, expires=None, - user_ref=None, project_ref=None): - """Recreate token from an existing token. - - Repopulate the ephemeral data and return the new token data. - - """ - new_expires = expires - project_id = None - user_id = None - domain_id = None - methods = ['password', 'token'] - extras = {} - - # NOTE(termie): Let's get some things straight here, because this code - # is wrong but tested as such: - # token_data, if it exists, is going to look like: - # {'token': ... the actual token data + a superfluous extras field ...} - # this data is actually stored in the database in the 'extras' column and - # then deserialized and added to the token_ref, that already has the - # the 'expires', 'user_id', and 'id' columns from the db. - # the 'user' and 'tenant' fields are being added to the - # token_ref due to being deserialized from the 'extras' column - # - # So, how this all looks in the db: - # id = some_id - # user_id = some_user_id - # expires = some_expiration - # extras = {'user': {'id': some_used_id}, - # 'tenant': {'id': some_tenant_id}, - # 'token_data': 'token': {'domain': {'id': some_domain_id}, - # 'project': {'id': some_project_id}, - # 'domain': {'id': some_domain_id}, - # 'user': {'id': some_user_id}, - # 'roles': [{'id': some_role_id}, ...], - # 'catalog': ..., - # 'expires_at': some_expiry_time, - # 'issued_at': now(), - # 'methods': ['password', 'token'], - # 'extras': { ... empty? ...} - # - # TODO(termie): reduce stored token complexity, bug filed at: - # https://bugs.launchpad.net/keystone/+bug/1159990 - if token_data: - # peel the outer layer so its easier to operate - token = token_data['token'] - domain_id = (token['domain']['id'] if 'domain' in token - else None) - project_id = (token['project']['id'] if 'project' in token - else None) - if not new_expires: - # support Grizzly-3 to Grizzly-RC1 transition - # tokens issued in G3 has 'expires' instead of 'expires_at' - new_expires = token.get('expires_at', - token.get('expires')) - user_id = token['user']['id'] - methods = token['methods'] - extras = token['extras'] - else: - token = None - project_id = project_ref['id'] if project_ref else None - user_id = user_ref['id'] - token_data_helper = TokenDataHelper() - return token_data_helper.get_token_data(user_id, - methods, - extras, - domain_id, - project_id, - new_expires, - token=token) - - -def create_token(auth_context, auth_info): - token_data_helper = TokenDataHelper() - (domain_id, project_id, trust) = auth_info.get_scope() - method_names = list(set(auth_info.get_method_names() + - auth_context.get('method_names', []))) - token_data = token_data_helper.get_token_data( - auth_context['user_id'], - method_names, - auth_context['extras'], - domain_id, - project_id, - auth_context.get('expires_at', None), - trust) - - if CONF.signing.token_format == 'UUID': - token_id = uuid.uuid4().hex - elif CONF.signing.token_format == 'PKI': - try: - token_id = cms.cms_sign_token(json.dumps(token_data), - CONF.signing.certfile, - CONF.signing.keyfile) - except environment.subprocess.CalledProcessError: - raise exception.UnexpectedError(_( - 'Unable to sign token.')) - else: - raise exception.UnexpectedError(_( - 'Invalid value for token_format: %s.' - ' Allowed values are PKI or UUID.') % - CONF.signing.token_format) - token_api = token_module.Manager() - try: - expiry = token_data['token']['expires_at'] - if isinstance(expiry, basestring): - expiry = timeutils.normalize_time(timeutils.parse_isotime(expiry)) - role_ids = [] - if 'project' in token_data['token']: - # project-scoped token, fill in the v2 token data - # all we care are the role IDs - role_ids = [role['id'] for role in token_data['token']['roles']] - metadata_ref = {'roles': role_ids} - data = dict(key=token_id, - id=token_id, - expires=expiry, - user=token_data['token']['user'], - tenant=token_data['token'].get('project'), - metadata=metadata_ref, - token_data=token_data, - trust_id=trust['id'] if trust else None) - token_api.create_token(token_id, data) - except Exception: - exc_info = sys.exc_info() - # an identical token may have been created already. - # if so, return the token_data as it is also identical - try: - token_api.get_token(token_id) - except exception.TokenNotFound: - raise exc_info[0], exc_info[1], exc_info[2] - - return (token_id, token_data) - - -def render_token_data_response(token_id, token_data, created=False): - """Render token data HTTP response. - - Stash token ID into the X-Auth-Token header. - - """ - headers = [('X-Subject-Token', token_id)] - headers.append(('Vary', 'X-Auth-Token')) - headers.append(('Content-Type', 'application/json')) - - if created: - status = (201, 'Created') - else: - status = (200, 'OK') - - body = jsonutils.dumps(token_data, cls=utils.SmarterEncoder) - return webob.Response(body=body, - status='%s %s' % status, - headerlist=headers) diff --git a/keystone/cli.py b/keystone/cli.py index 598bd409..21d2ad40 100644 --- a/keystone/cli.py +++ b/keystone/cli.py @@ -74,7 +74,7 @@ class DbVersion(BaseApp): @staticmethod def main(): - print migration.db_version() + print(migration.db_version()) class BaseCertificateSetup(BaseApp): @@ -180,7 +180,7 @@ class ExportLegacyCatalog(BaseApp): def main(): from keystone.common.sql import legacy migration = legacy.LegacyMigration(CONF.command.old_db) - print '\n'.join(migration.dump_catalog()) + print('\n'.join(migration.dump_catalog())) class ImportNovaAuth(BaseApp): diff --git a/keystone/common/config.py b/keystone/common/config.py index c0bd34e6..10c47a35 100644 --- a/keystone/common/config.py +++ b/keystone/common/config.py @@ -24,7 +24,7 @@ from keystone.common import logging _DEFAULT_LOG_FORMAT = "%(asctime)s %(levelname)8s [%(name)s] %(message)s" _DEFAULT_LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S" -_DEFAULT_AUTH_METHODS = ['password', 'token'] +_DEFAULT_AUTH_METHODS = ['external', 'password', 'token'] COMMON_CLI_OPTS = [ cfg.BoolOpt('debug', @@ -214,6 +214,13 @@ def configure(): # trust register_bool('enabled', group='trust', default=True) + # os_inherit + register_bool('enabled', group='os_inherit', default=False) + + # binding + register_list('bind', group='token', default=[]) + register_str('enforce_token_bind', group='token', default='permissive') + # ssl register_bool('enable', group='ssl', default=False) register_str('certfile', group='ssl', @@ -233,7 +240,7 @@ def configure(): # signing register_str( - 'token_format', group='signing', default="PKI") + 'token_format', group='signing', default=None) register_str( 'certfile', group='signing', @@ -259,6 +266,12 @@ def configure(): default='sqlite:///keystone.db') register_int('idle_timeout', group='sql', default=200) + #assignment has no default for backward compatibility reasons. + #If assignment is not specified, the identity driver chooses the backend + register_str( + 'driver', + group='assignment', + default=None) register_str( 'driver', group='catalog', @@ -369,23 +382,6 @@ def configure(): register_list( 'group_additional_attribute_mapping', group='ldap', default=None) - register_str('domain_tree_dn', group='ldap', default=None) - register_str('domain_filter', group='ldap', default=None) - register_str('domain_objectclass', group='ldap', default='groupOfNames') - register_str('domain_id_attribute', group='ldap', default='cn') - register_str('domain_name_attribute', group='ldap', default='ou') - register_str('domain_member_attribute', group='ldap', default='member') - register_str('domain_desc_attribute', group='ldap', default='description') - register_str('domain_enabled_attribute', group='ldap', default='enabled') - register_list('domain_attribute_ignore', group='ldap', default='') - register_bool('domain_allow_create', group='ldap', default=True) - register_bool('domain_allow_update', group='ldap', default=True) - register_bool('domain_allow_delete', group='ldap', default=True) - register_bool('domain_enabled_emulation', group='ldap', default=False) - register_str('domain_enabled_emulation_dn', group='ldap', default=None) - register_list( - 'domain_additional_attribute_mapping', group='ldap', default=None) - register_str('tls_cacertfile', group='ldap', default=None) register_str('tls_cacertdir', group='ldap', default=None) register_bool('use_tls', group='ldap', default=False) @@ -402,7 +398,11 @@ def configure(): register_str( 'token', group='auth', default='keystone.auth.plugins.password.Password') - + #deals with REMOTE_USER authentication + register_str( + 'external', + group='auth', + default='keystone.auth.plugins.external.ExternalDefault') # register any non-default auth methods here (used by extensions, etc) for method_name in CONF.auth.methods: if method_name not in _DEFAULT_AUTH_METHODS: @@ -410,3 +410,9 @@ def configure(): # PasteDeploy config file register_str('config_file', group='paste_deploy', default=None) + + # token provider + register_str( + 'provider', + group='token', + default=None) diff --git a/keystone/common/controller.py b/keystone/common/controller.py index 13aeee57..affc34de 100644 --- a/keystone/common/controller.py +++ b/keystone/common/controller.py @@ -25,8 +25,12 @@ def _build_policy_check_credentials(self, action, context, kwargs): LOG.warning(_('RBAC: Invalid token')) raise exception.Unauthorized() + # NOTE(jamielennox): whilst this maybe shouldn't be within this function + # it would otherwise need to reload the token_ref from backing store. + wsgi.validate_token_bind(context, token_ref) + creds = {} - if 'token_data' in token_ref: + if 'token_data' in token_ref and 'token' in token_ref['token_data']: #V3 Tokens token_data = token_ref['token_data']['token'] try: @@ -146,7 +150,8 @@ def filterprotected(*filters): @dependency.requires('identity_api', 'policy_api', 'token_api', - 'trust_api', 'catalog_api', 'credential_api') + 'trust_api', 'catalog_api', 'credential_api', + 'assignment_api') class V2Controller(wsgi.Application): """Base controller class for Identity API v2.""" @@ -280,7 +285,8 @@ class V3Controller(V2Controller): if attr in context['query_string']: value = context['query_string'][attr] - return [r for r in refs if _attr_match(r[attr], value)] + return [r for r in refs if _attr_match( + flatten(r).get(attr), value)] return refs def _require_matching_id(self, value, ref): @@ -311,7 +317,7 @@ class V3Controller(V2Controller): # worth the duplication of state try: token_ref = self.token_api.get_token( - context=context, token_id=context['token_id']) + token_id=context['token_id']) except exception.TokenNotFound: LOG.warning(_('Invalid token in normalize_domain_id')) raise exception.Unauthorized() diff --git a/keystone/common/dependency.py b/keystone/common/dependency.py index dc3e4ac4..a640031d 100644 --- a/keystone/common/dependency.py +++ b/keystone/common/dependency.py @@ -16,6 +16,8 @@ REGISTRY = {} +_future_dependencies = {} + class UnresolvableDependencyException(Exception): def __init__(self, name): @@ -32,6 +34,8 @@ def provider(name): init(self, *args, **kwargs) REGISTRY[name] = self + resolve_future_dependencies(name) + return __wrapped_init__ cls.__init__ = wrapped(cls.__init__) @@ -48,7 +52,13 @@ def requires(*dependencies): for dependency in self._dependencies: if dependency not in REGISTRY: - raise UnresolvableDependencyException(dependency) + if dependency in _future_dependencies: + _future_dependencies[dependency] += [self] + else: + _future_dependencies[dependency] = [self] + + continue + setattr(self, dependency, REGISTRY[dependency]) def wrapped(cls): @@ -65,3 +75,34 @@ def requires(*dependencies): return cls return wrapped + + +def resolve_future_dependencies(provider_name=None): + if provider_name: + targets = _future_dependencies.pop(provider_name, []) + + for target in targets: + setattr(target, provider_name, REGISTRY[provider_name]) + + return + + try: + for dependency, targets in _future_dependencies.iteritems(): + if dependency not in REGISTRY: + raise UnresolvableDependencyException(dependency) + + for target in targets: + setattr(target, dependency, REGISTRY[dependency]) + finally: + _future_dependencies.clear() + + +def reset(): + """Reset the registry of providers. + + This is useful for unit testing to ensure that tests don't use providers + from previous tests. + """ + + REGISTRY.clear() + _future_dependencies.clear() diff --git a/keystone/common/extension.py b/keystone/common/extension.py new file mode 100644 index 00000000..f176a197 --- /dev/null +++ b/keystone/common/extension.py @@ -0,0 +1,47 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 OpenStack LLC +# +# 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. + + +ADMIN_EXTENSIONS = {} +PUBLIC_EXTENSIONS = {} + + +def register_admin_extension(url_prefix, extension_data): + """Register extension with collection of admin extensions. + + Extensions register the information here that will show + up in the /extensions page as a way to indicate that the extension is + active. + + url_prefix: unique key for the extension that will appear in the + urls generated by the extension. + + extension_data is a dictionary. The expected fields are: + 'name': short, human readable name of the extnsion + 'namespace': xml namespace + 'alias': identifier for the extension + 'updated': date the extension was last updated + 'description': text description of the extension + 'links': hyperlinks to documents describing the extension + + """ + ADMIN_EXTENSIONS[url_prefix] = extension_data + + +def register_public_extension(url_prefix, extension_data): + """Same as register_admin_extension but for public extensions.""" + + PUBLIC_EXTENSIONS[url_prefix] = extension_data diff --git a/keystone/common/kvs.py b/keystone/common/kvs.py index b517bc5d..09693999 100644 --- a/keystone/common/kvs.py +++ b/keystone/common/kvs.py @@ -50,6 +50,8 @@ class Base(object): def __init__(self, db=None): if db is None: db = INMEMDB + elif isinstance(db, DictKvs): + db = db elif isinstance(db, dict): db = DictKvs(db) self.db = db diff --git a/keystone/common/logging.py b/keystone/common/logging.py index 8c036f02..d221edb7 100644 --- a/keystone/common/logging.py +++ b/keystone/common/logging.py @@ -23,7 +23,6 @@ import logging import logging.config import logging.handlers import pprint -import traceback # A list of things we want to replicate from logging. @@ -78,8 +77,7 @@ def fail_gracefully(f): try: return f(*args, **kw) except Exception as e: - # tracebacks are kept in the debug log - logging.debug(traceback.format_exc(e)) + logging.debug(e, exc_info=True) # exception message is printed to all logs logging.critical(e) diff --git a/keystone/common/openssl.py b/keystone/common/openssl.py index 427202ae..fa09e37c 100644 --- a/keystone/common/openssl.py +++ b/keystone/common/openssl.py @@ -12,6 +12,7 @@ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations +# under the License. # import os diff --git a/keystone/common/serializer.py b/keystone/common/serializer.py index 597fbfd8..4355a059 100644 --- a/keystone/common/serializer.py +++ b/keystone/common/serializer.py @@ -125,7 +125,8 @@ class XmlDeserializer(object): values = values or text or {} decoded_tag = XmlDeserializer._tag_name(element.tag, namespace) list_item_tag = None - if decoded_tag[-1] == 's' and len(values) == 0: + if (decoded_tag[-1] == 's' and len(values) == 0 and + decoded_tag != 'access'): # FIXME(gyee): special-case lists for now unti we # figure out how to properly handle them. # If any key ends with an 's', we are assuming it is a list. diff --git a/keystone/common/sql/core.py b/keystone/common/sql/core.py index d75c73a8..2d3114f2 100644 --- a/keystone/common/sql/core.py +++ b/keystone/common/sql/core.py @@ -32,10 +32,12 @@ from keystone import exception from keystone.openstack.common import jsonutils +LOG = logging.getLogger(__name__) CONF = config.CONF -# maintain a single engine reference for sqlite in-memory +# maintain a single engine reference for sqlalchemy engine GLOBAL_ENGINE = None +GLOBAL_ENGINE_CALLBACKS = set() ModelBase = declarative.declarative_base() @@ -78,13 +80,6 @@ def initialize_decorator(init): v = str(v) if column.type.length and \ column.type.length < len(v): - #if signing.token_format == 'PKI', the id will - #store it's public key which is very long. - if config.CONF.signing.token_format == 'PKI' and \ - self.__tablename__ == 'token' and \ - k == 'id': - continue - raise exception.StringLengthExceeded( string=v, type=k, length=column.type.length) @@ -95,9 +90,49 @@ ModelBase.__init__ = initialize_decorator(ModelBase.__init__) def set_global_engine(engine): + """Set the global engine. + + This sets the current global engine, which is returned by + Base.get_engine(allow_global_engine=True). + + When the global engine is changed, all of the callbacks registered via + register_global_engine_callback since the last time set_global_engine was + changed are called. The callback functions are invoked with no arguments. + + """ + global GLOBAL_ENGINE + global GLOBAL_ENGINE_CALLBACKS + + if engine is GLOBAL_ENGINE: + # It's the same engine so nothing to do. + return + GLOBAL_ENGINE = engine + cbs = GLOBAL_ENGINE_CALLBACKS + GLOBAL_ENGINE_CALLBACKS = set() + for cb in cbs: + try: + cb() + except Exception: + LOG.exception(_("Global engine callback raised.")) + # Just logging the exception so can process other callbacks. + + +def register_global_engine_callback(cb_fn): + """Register a function to be called when the global engine is set. + + Note that the callback will be called only once or not at all, so to get + called each time the global engine is changed the function must be + re-registered. + + """ + + global GLOBAL_ENGINE_CALLBACKS + + GLOBAL_ENGINE_CALLBACKS.add(cb_fn) + # Special Fields class JsonBlob(sql_types.TypeDecorator): @@ -208,10 +243,12 @@ class Base(object): def get_session(self, autocommit=True, expire_on_commit=False): """Return a SQLAlchemy session.""" - self._engine = self._engine or self.get_engine() - self._sessionmaker = self._sessionmaker or self.get_sessionmaker( - self._engine) - return self._sessionmaker() + if not self._engine: + self._engine = self.get_engine() + self._sessionmaker = self.get_sessionmaker(self._engine) + register_global_engine_callback(self.clear_engine) + return self._sessionmaker(autocommit=autocommit, + expire_on_commit=expire_on_commit) def get_engine(self, allow_global_engine=True): """Return a SQLAlchemy engine. @@ -264,6 +301,10 @@ class Base(object): autocommit=autocommit, expire_on_commit=expire_on_commit) + def clear_engine(self): + self._engine = None + self._sessionmaker = None + def handle_conflicts(type='object'): """Converts IntegrityError into HTTP 409 Conflict.""" diff --git a/keystone/common/sql/legacy.py b/keystone/common/sql/legacy.py index f2e0b994..c8adc900 100644 --- a/keystone/common/sql/legacy.py +++ b/keystone/common/sql/legacy.py @@ -19,6 +19,8 @@ import re import sqlalchemy from sqlalchemy import exc + +from keystone.assignment.backends import sql as assignment_sql from keystone.common import logging from keystone import config from keystone.contrib.ec2.backends import sql as ec2_sql @@ -57,8 +59,14 @@ def _translate_replacements(s): class LegacyMigration(object): def __init__(self, db_string): self.db = sqlalchemy.create_engine(db_string) + #TODO(ayoung): Replace with call via Manager self.identity_driver = identity_sql.Identity() + self.assignment_driver = assignment_sql.Assignment() + self.identity_driver.assignment_api = self.assignment_driver + self.assignment_driver.identity_api = self.identity_driver self.identity_driver.db_sync() + self.assignment_driver.db_sync() + self.ec2_driver = ec2_sql.Ec2() self._data = {} self._user_map = {} @@ -113,7 +121,7 @@ class LegacyMigration(object): self._project_map[x.get('id')] = new_dict['id'] # create #print 'create_project(%s, %s)' % (new_dict['id'], new_dict) - self.identity_driver.create_project(new_dict['id'], new_dict) + self.assignment_driver.create_project(new_dict['id'], new_dict) def _migrate_users(self): for x in self._data['users']: @@ -144,7 +152,7 @@ class LegacyMigration(object): # track internal ids self._role_map[x.get('id')] = new_dict['id'] # create - self.identity_driver.create_role(new_dict['id'], new_dict) + self.assignment_driver.create_role(new_dict['id'], new_dict) def _migrate_user_roles(self): for x in self._data['user_roles']: @@ -162,7 +170,7 @@ class LegacyMigration(object): except Exception: pass - self.identity_driver.add_role_to_user_and_project( + self.assignment_driver.add_role_to_user_and_project( user_id, tenant_id, role_id) def _migrate_tokens(self): diff --git a/keystone/common/sql/migrate_repo/versions/001_add_initial_tables.py b/keystone/common/sql/migrate_repo/versions/001_add_initial_tables.py index d29cf167..84243cb9 100644 --- a/keystone/common/sql/migrate_repo/versions/001_add_initial_tables.py +++ b/keystone/common/sql/migrate_repo/versions/001_add_initial_tables.py @@ -54,12 +54,28 @@ def upgrade(migrate_engine): sql.Column('name', sql.String(255), unique=True, nullable=False)) role_table.create(migrate_engine, checkfirst=True) - tenant_table = sql.Table( - 'tenant', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('name', sql.String(64), unique=True, nullable=False), - sql.Column('extra', sql.Text())) + if migrate_engine.name == 'ibm_db_sa': + # NOTE(blk-u): SQLAlchemy for PostgreSQL picks the name tenant_name_key + # for the unique constraint, but for DB2 doesn't give the UC a name + # unless we tell it to and there is no DDL to alter a column to drop + # an unnamed unique constraint, so this code creates a named unique + # constraint on the name column rather than an unnamed one. + # (This is used in migration 16.) + tenant_table = sql.Table( + 'tenant', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('name', sql.String(64), nullable=False), + sql.Column('extra', sql.Text()), + sql.UniqueConstraint('name', name='tenant_name_key')) + else: + tenant_table = sql.Table( + 'tenant', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('name', sql.String(64), unique=True, nullable=False), + sql.Column('extra', sql.Text())) + tenant_table.create(migrate_engine, checkfirst=True) metadata_table = sql.Table( @@ -79,12 +95,28 @@ def upgrade(migrate_engine): sql.Column('tenant_id', sql.String(64))) ec2_credential_table.create(migrate_engine, checkfirst=True) - user_table = sql.Table( - 'user', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('name', sql.String(64), unique=True, nullable=False), - sql.Column('extra', sql.Text())) + if migrate_engine.name == 'ibm_db_sa': + # NOTE(blk-u): SQLAlchemy for PostgreSQL picks the name user_name_key + # for the unique constraint, but for DB2 doesn't give the UC a name + # unless we tell it to and there is no DDL to alter a column to drop + # an unnamed unique constraint, so this code creates a named unique + # constraint on the name column rather than an unnamed one. + # (This is used in migration 16.) + user_table = sql.Table( + 'user', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('name', sql.String(64), nullable=False), + sql.Column('extra', sql.Text()), + sql.UniqueConstraint('name', name='user_name_key')) + else: + user_table = sql.Table( + 'user', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('name', sql.String(64), unique=True, nullable=False), + sql.Column('extra', sql.Text())) + user_table.create(migrate_engine, checkfirst=True) user_tenant_membership_table = sql.Table( diff --git a/keystone/common/sql/migrate_repo/versions/011_endpoints_v3.py b/keystone/common/sql/migrate_repo/versions/011_endpoints_v3.py index 31117486..b0f88086 100644 --- a/keystone/common/sql/migrate_repo/versions/011_endpoints_v3.py +++ b/keystone/common/sql/migrate_repo/versions/011_endpoints_v3.py @@ -16,6 +16,8 @@ import sqlalchemy as sql +from keystone.common.sql import migration_helpers + def upgrade(migrate_engine): """Create API-version specific endpoint tables.""" @@ -23,7 +25,14 @@ def upgrade(migrate_engine): meta.bind = migrate_engine legacy_table = sql.Table('endpoint', meta, autoload=True) - legacy_table.rename('endpoint_v2') + + renames = {'endpoint_v2': legacy_table} + service_table = sql.Table('service', meta, autoload=True) + constraints = [{'table': legacy_table, + 'fk_column': 'service_id', + 'ref_column': service_table.c.id}] + migration_helpers.rename_tables_with_constraints(renames, constraints, + migrate_engine) sql.Table('service', meta, autoload=True) new_table = sql.Table( @@ -51,4 +60,11 @@ def downgrade(migrate_engine): new_table.drop() legacy_table = sql.Table('endpoint_v2', meta, autoload=True) - legacy_table.rename('endpoint') + + renames = {'endpoint': legacy_table} + service_table = sql.Table('service', meta, autoload=True) + constraints = [{'table': legacy_table, + 'fk_column': 'service_id', + 'ref_column': service_table.c.id}] + migration_helpers.rename_tables_with_constraints(renames, constraints, + migrate_engine) diff --git a/keystone/common/sql/migrate_repo/versions/013_drop_legacy_endpoints.py b/keystone/common/sql/migrate_repo/versions/013_drop_legacy_endpoints.py index f75ce3c0..deb52947 100644 --- a/keystone/common/sql/migrate_repo/versions/013_drop_legacy_endpoints.py +++ b/keystone/common/sql/migrate_repo/versions/013_drop_legacy_endpoints.py @@ -16,6 +16,8 @@ import sqlalchemy as sql +from keystone.common.sql import migration_helpers + def upgrade(migrate_engine): """Replace API-version specific endpoint tables with one based on v3.""" @@ -26,7 +28,14 @@ def upgrade(migrate_engine): legacy_table.drop() new_table = sql.Table('endpoint_v3', meta, autoload=True) - new_table.rename('endpoint') + + renames = {'endpoint': new_table} + service_table = sql.Table('service', meta, autoload=True) + constraints = [{'table': new_table, + 'fk_column': 'service_id', + 'ref_column': service_table.c.id}] + migration_helpers.rename_tables_with_constraints(renames, constraints, + migrate_engine) def downgrade(migrate_engine): @@ -35,7 +44,14 @@ def downgrade(migrate_engine): meta.bind = migrate_engine new_table = sql.Table('endpoint', meta, autoload=True) - new_table.rename('endpoint_v3') + + renames = {'endpoint_v3': new_table} + service_table = sql.Table('service', meta, autoload=True) + constraints = [{'table': new_table, + 'fk_column': 'service_id', + 'ref_column': service_table.c.id}] + migration_helpers.rename_tables_with_constraints(renames, constraints, + migrate_engine) sql.Table('service', meta, autoload=True) legacy_table = sql.Table( diff --git a/keystone/common/sql/migrate_repo/versions/015_tenant_to_project.py b/keystone/common/sql/migrate_repo/versions/015_tenant_to_project.py index 5f276c68..2a63fad8 100644 --- a/keystone/common/sql/migrate_repo/versions/015_tenant_to_project.py +++ b/keystone/common/sql/migrate_repo/versions/015_tenant_to_project.py @@ -1,19 +1,66 @@ import sqlalchemy as sql from sqlalchemy.orm import sessionmaker +from keystone.common.sql import migration_helpers + + +def rename_with_constraints(meta, legacy_project_table_name, + new_project_table_name, + legacy_user_project_membership_table_name, + new_user_project_membership_table_name): + # Not all RDBMSs support renaming a table that has foreign key constraints + # on it, so drop FK constraints before renaming and then replace FKs + # afterwards. + + credential_table = sql.Table('credential', meta, autoload=True) + group_project_meta_table = sql.Table('group_project_metadata', meta, + autoload=True) + project_table = sql.Table(legacy_project_table_name, meta, autoload=True) + user_project_membership_table = sql.Table( + legacy_user_project_membership_table_name, meta, autoload=True) + user_table = sql.Table('user', meta, autoload=True) + + constraints = [{'table': credential_table, + 'fk_column': 'project_id', + 'ref_column': project_table.c.id}, + {'table': group_project_meta_table, + 'fk_column': 'project_id', + 'ref_column': project_table.c.id}, + {'table': user_project_membership_table, + 'fk_column': 'tenant_id', + 'ref_column': project_table.c.id}, + {'table': user_project_membership_table, + 'fk_column': 'user_id', + 'ref_column': user_table.c.id}] + + renames = { + new_project_table_name: project_table, + new_user_project_membership_table_name: user_project_membership_table} + + migration_helpers.rename_tables_with_constraints(renames, constraints, + meta.bind) + def upgrade_with_rename(meta, migrate_engine): - legacy_table = sql.Table('tenant', meta, autoload=True) - legacy_table.rename('project') - legacy_table = sql.Table('user_tenant_membership', meta, autoload=True) - legacy_table.rename('user_project_membership') + legacy_project_table_name = 'tenant' + new_project_table_name = 'project' + legacy_user_project_membership_table_name = 'user_tenant_membership' + new_user_project_membership_table_name = 'user_project_membership' + rename_with_constraints(meta, legacy_project_table_name, + new_project_table_name, + legacy_user_project_membership_table_name, + new_user_project_membership_table_name) def downgrade_with_rename(meta, migrate_engine): - upgrade_table = sql.Table('project', meta, autoload=True) - upgrade_table.rename('tenant') - upgrade_table = sql.Table('user_project_membership', meta, autoload=True) - upgrade_table.rename('user_tenant_membership') + legacy_project_table_name = 'project' + new_project_table_name = 'tenant' + legacy_user_project_membership_table_name = 'user_project_membership' + new_user_project_membership_table_name = 'user_tenant_membership' + rename_with_constraints(meta, legacy_project_table_name, + new_project_table_name, + legacy_user_project_membership_table_name, + new_user_project_membership_table_name) def upgrade_with_copy(meta, migrate_engine): diff --git a/keystone/common/sql/migrate_repo/versions/016_normalize_domain_ids.py b/keystone/common/sql/migrate_repo/versions/016_normalize_domain_ids.py index f8e46591..f28060e6 100644 --- a/keystone/common/sql/migrate_repo/versions/016_normalize_domain_ids.py +++ b/keystone/common/sql/migrate_repo/versions/016_normalize_domain_ids.py @@ -381,7 +381,9 @@ def downgrade_user_table_with_col_drop(meta, migrate_engine, session): # Revert uniqueness settings for the name attribute session.execute('ALTER TABLE "user" DROP CONSTRAINT ' 'user_dom_name_unique;') - session.execute('ALTER TABLE "user" ADD UNIQUE (name);') + # specify the constraint name so it can be referenced later + session.execute('ALTER TABLE "user" ADD CONSTRAINT user_name_key ' + 'UNIQUE (name);') session.commit() # And now go ahead an drop the domain_id column sql.Table('domain', meta, autoload=True) diff --git a/keystone/common/sql/migrate_repo/versions/020_migrate_metadata_table_roles.py b/keystone/common/sql/migrate_repo/versions/020_migrate_metadata_table_roles.py index 35110df4..a0c6ddbc 100644 --- a/keystone/common/sql/migrate_repo/versions/020_migrate_metadata_table_roles.py +++ b/keystone/common/sql/migrate_repo/versions/020_migrate_metadata_table_roles.py @@ -23,11 +23,9 @@ def upgrade(migrate_engine): session = sql.orm.sessionmaker(bind=migrate_engine)() for metadata in session.query(old_metadata_table): + data = json.loads(metadata.data) if config.CONF.member_role_id not in metadata.data: - data = json.loads(metadata.data) data['roles'].append(config.CONF.member_role_id) - else: - data = metadata.data r = session.query(new_metadata_table).filter_by( user_id=metadata.user_id, diff --git a/keystone/common/sql/migrate_repo/versions/027_set_engine_mysql_innodb.py b/keystone/common/sql/migrate_repo/versions/027_set_engine_mysql_innodb.py new file mode 100644 index 00000000..ca8ccd08 --- /dev/null +++ b/keystone/common/sql/migrate_repo/versions/027_set_engine_mysql_innodb.py @@ -0,0 +1,143 @@ + +import sqlalchemy as sql +from sqlalchemy import MetaData + +from keystone.common.sql import migration_helpers + + +def upgrade(migrate_engine): + # Upgrade operations go here. Don't create your own engine; + # bind migrate_engine to your metadata + + if migrate_engine.name != 'mysql': + # InnoDB / MyISAM only applies to MySQL. + return + + # This is a list of all the tables that might have been created with MyISAM + # rather than InnoDB. + tables = [ + 'credential', + 'domain', + 'ec2_credential', + 'endpoint', + 'group', + 'group_domain_metadata', + 'group_project_metadata', + 'policy', + 'project', + 'role', + 'service', + 'token', + 'trust', + 'trust_role', + 'user', + 'user_domain_metadata', + 'user_group_membership', + 'user_project_metadata', + ] + + meta = MetaData() + meta.bind = migrate_engine + + domain_table = sql.Table('domain', meta, autoload=True) + endpoint_table = sql.Table('endpoint', meta, autoload=True) + group_table = sql.Table('group', meta, autoload=True) + group_domain_metadata_table = sql.Table('group_domain_metadata', meta, + autoload=True) + group_project_metadata_table = sql.Table('group_project_metadata', meta, + autoload=True) + project_table = sql.Table('project', meta, autoload=True) + service_table = sql.Table('service', meta, autoload=True) + user_table = sql.Table('user', meta, autoload=True) + user_domain_metadata_table = sql.Table('user_domain_metadata', meta, + autoload=True) + user_group_membership_table = sql.Table('user_group_membership', meta, + autoload=True) + + # Mapping of table name to the constraints on that table, + # so we can create them. + table_constraints = { + 'endpoint': [{'table': endpoint_table, + 'fk_column': 'service_id', + 'ref_column': service_table.c.id}, + ], + 'group': [{'table': group_table, + 'fk_column': 'domain_id', + 'ref_column': domain_table.c.id}, + ], + 'group_domain_metadata': [{'table': group_domain_metadata_table, + 'fk_column': 'domain_id', + 'ref_column': domain_table.c.id}, + ], + 'group_project_metadata': [{'table': group_project_metadata_table, + 'fk_column': 'project_id', + 'ref_column': project_table.c.id}, + ], + 'project': [{'table': project_table, + 'fk_column': 'domain_id', + 'ref_column': domain_table.c.id}, + ], + 'user': [{'table': user_table, + 'fk_column': 'domain_id', + 'ref_column': domain_table.c.id}, + ], + 'user_domain_metadata': [{'table': user_domain_metadata_table, + 'fk_column': 'domain_id', + 'ref_column': domain_table.c.id}, + ], + 'user_group_membership': [{'table': user_group_membership_table, + 'fk_column': 'user_id', + 'ref_column': user_table.c.id}, + {'table': user_group_membership_table, + 'fk_column': 'group_id', + 'ref_column': group_table.c.id}, + ], + 'user_project_metadata': [{'table': group_project_metadata_table, + 'fk_column': 'project_id', + 'ref_column': project_table.c.id}, + ], + } + + # Maps a table name to the tables that reference it as a FK constraint + # (See the map above). + ref_tables_map = { + 'service': ['endpoint', ], + 'domain': ['group', 'group_domain_metadata', 'project', 'user', + 'user_domain_metadata', ], + 'project': ['group_project_metadata', 'user_project_metadata', ], + 'user': ['user_group_membership', ], + 'group': ['user_group_membership', ], + } + + # The names of tables that need to have their FKs added. + fk_table_names = set() + + d = migrate_engine.execute("SHOW TABLE STATUS WHERE Engine!='InnoDB';") + for row in d.fetchall(): + table_name = row[0] + + if table_name not in tables: + # Skip this table since it's not a Keystone table. + continue + + migrate_engine.execute("ALTER TABLE `%s` Engine=InnoDB" % table_name) + + # Will add the FKs to the table if any of + # a) the table itself was converted + # b) the tables that the table referenced were converted + + if table_name in table_constraints: + fk_table_names.add(table_name) + + ref_tables = ref_tables_map.get(table_name, []) + for other_table_name in ref_tables: + fk_table_names.add(other_table_name) + + # Now add all the FK constraints to those tables + for table_name in fk_table_names: + constraints = table_constraints.get(table_name) + migration_helpers.add_constraints(constraints) + + +def downgrade(migrate_engine): + pass diff --git a/keystone/common/sql/migrate_repo/versions/028_fixup_group_metadata.py b/keystone/common/sql/migrate_repo/versions/028_fixup_group_metadata.py new file mode 100644 index 00000000..66055a99 --- /dev/null +++ b/keystone/common/sql/migrate_repo/versions/028_fixup_group_metadata.py @@ -0,0 +1,190 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 OpenStack LLC +# +# 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 sqlalchemy as sql + + +def upgrade(migrate_engine): + # The group_project_metadata table was not updated in terms of its + # FK to the tenant table when the tenant->project change was made at + # the 015 migration for sqlite. This upgrade fixes that. + # We need to create a fake tenant table so that we can first load + # the group_project_metadata at all, then do a dance of copying tables + # to get us to the correct schema. + meta = sql.MetaData() + meta.bind = migrate_engine + + if migrate_engine.name != 'sqlite': + return + + temp_tenant_table = sql.Table( + 'tenant', + meta, + sql.Column('id', sql.String(64), primary_key=True)) + temp_tenant_table.create(migrate_engine, checkfirst=True) + + sql.Table('user', meta, autoload=True) + old_group_metadata_table = sql.Table('group_project_metadata', + meta, autoload=True) + + # OK, we now have the table loaded, create a first + # temporary table of a different name with the correct FK + sql.Table('project', meta, autoload=True) + temp_group_project_metadata_table = sql.Table( + 'temp_group_project_metadata', + meta, + sql.Column( + 'group_id', + sql.String(64), + primary_key=True), + sql.Column( + 'project_id', + sql.String(64), + sql.ForeignKey('project.id'), + primary_key=True), + sql.Column('data', sql.Text())) + temp_group_project_metadata_table.create(migrate_engine, checkfirst=True) + + # Populate the new temporary table, and then drop the old one + session = sql.orm.sessionmaker(bind=migrate_engine)() + + for metadata in session.query(old_group_metadata_table): + q = temp_group_project_metadata_table.insert().values( + group_id=metadata.group_id, + project_id=metadata.project_id, + data=metadata.data) + session.execute(q) + session.commit() + old_group_metadata_table.drop() + temp_tenant_table.drop() + + # Now do a final table copy to get the table of the right name. + # Re-init the metadata so that sqlalchemy does not get confused with + # multiple versions of the same named table. + meta2 = sql.MetaData() + meta2.bind = migrate_engine + + sql.Table('project', meta2, autoload=True) + new_group_project_metadata_table = sql.Table( + 'group_project_metadata', + meta2, + sql.Column( + 'group_id', + sql.String(64), + primary_key=True), + sql.Column( + 'project_id', + sql.String(64), + sql.ForeignKey('project.id'), + primary_key=True), + sql.Column('data', sql.Text())) + new_group_project_metadata_table.create(migrate_engine, checkfirst=True) + + for metadata in session.query(temp_group_project_metadata_table): + q = new_group_project_metadata_table.insert().values( + group_id=metadata.group_id, + project_id=metadata.project_id, + data=metadata.data) + session.execute(q) + session.commit() + + temp_group_project_metadata_table.drop() + + +def downgrade(migrate_engine): + # Put the group_project_metadata table back the way it was in its rather + # broken state. We don't try and re-write history, since otherwise people + # get out of step. + meta = sql.MetaData() + meta.bind = migrate_engine + + if migrate_engine.name != 'sqlite': + return + + sql.Table('user', meta, autoload=True) + sql.Table('project', meta, autoload=True) + group_metadata_table = sql.Table('group_project_metadata', + meta, autoload=True) + + # We want to create a temp group meta table with the FK + # set to the wrong place. + temp_tenant_table = sql.Table( + 'tenant', + meta, + sql.Column('id', sql.String(64), primary_key=True)) + temp_tenant_table.create(migrate_engine, checkfirst=True) + + temp_group_project_metadata_table = sql.Table( + 'temp_group_project_metadata', + meta, + sql.Column( + 'group_id', + sql.String(64), + primary_key=True), + sql.Column( + 'project_id', + sql.String(64), + sql.ForeignKey('tenant.id'), + primary_key=True), + sql.Column('data', sql.Text())) + temp_group_project_metadata_table.create(migrate_engine, checkfirst=True) + + # Now populate the temp table and drop the real one + session = sql.orm.sessionmaker(bind=migrate_engine)() + + for metadata in session.query(group_metadata_table): + q = temp_group_project_metadata_table.insert().values( + group_id=metadata.group_id, + project_id=metadata.project_id, + data=metadata.data) + session.execute(q) + + session.commit() + group_metadata_table.drop() + + # Now copy again into the correctly named table. Re-init the metadata + # so that sqlalchemy does not get confused with multiple versions of the + # same named table. + meta2 = sql.MetaData() + meta2.bind = migrate_engine + + sql.Table('tenant', meta2, autoload=True) + new_group_project_metadata_table = sql.Table( + 'group_project_metadata', + meta2, + sql.Column( + 'group_id', + sql.String(64), + primary_key=True), + sql.Column( + 'project_id', + sql.String(64), + sql.ForeignKey('tenant.id'), + primary_key=True), + sql.Column('data', sql.Text())) + new_group_project_metadata_table.create(migrate_engine, checkfirst=True) + + for metadata in session.query(temp_group_project_metadata_table): + q = new_group_project_metadata_table.insert().values( + group_id=metadata.group_id, + project_id=metadata.project_id, + data=metadata.data) + session.execute(q) + + session.commit() + + temp_group_project_metadata_table.drop() + temp_tenant_table.drop() diff --git a/keystone/common/sql/migrate_repo/versions/029_update_assignment_metadata.py b/keystone/common/sql/migrate_repo/versions/029_update_assignment_metadata.py new file mode 100644 index 00000000..a9276804 --- /dev/null +++ b/keystone/common/sql/migrate_repo/versions/029_update_assignment_metadata.py @@ -0,0 +1,102 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 OpenStack LLC +# +# 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 json + +import sqlalchemy as sql + + +def build_update(table_name, upgrade_table, row, values): + if table_name == 'user_project_metadata': + update = upgrade_table.update().where( + upgrade_table.c.user_id == row.user_id).where( + upgrade_table.c.project_id == row.project_id).values(values) + elif table_name == 'group_project_metadata': + update = upgrade_table.update().where( + upgrade_table.c.group_id == row.group_id).where( + upgrade_table.c.project_id == row.project_id).values(values) + elif table_name == 'user_domain_metadata': + update = upgrade_table.update().where( + upgrade_table.c.user_id == row.user_id).where( + upgrade_table.c.domain_id == row.domain_id).values(values) + else: + update = upgrade_table.update().where( + upgrade_table.c.group_id == row.group_id).where( + upgrade_table.c.domain_id == row.domain_id).values(values) + return update + + +def upgrade_grant_table(meta, migrate_engine, session, table_name): + + # Convert the roles component of the metadata from a list + # of ids to a list of dicts + + def list_to_dict_list(metadata): + json_metadata = json.loads(metadata) + if 'roles' in json_metadata: + json_metadata['roles'] = ( + [{'id': x} for x in json_metadata['roles']]) + return json.dumps(json_metadata) + + upgrade_table = sql.Table(table_name, meta, autoload=True) + for assignment in session.query(upgrade_table): + values = {'data': list_to_dict_list(assignment.data)} + update = build_update(table_name, upgrade_table, assignment, values) + migrate_engine.execute(update) + + +def downgrade_grant_table(meta, migrate_engine, session, table_name): + + # Convert the roles component of the metadata from a list + # of dicts to a simple list of ids. Any inherited roles are deleted + # since they would have no meaning + + def dict_list_to_list(metadata): + json_metadata = json.loads(metadata) + if 'roles' in json_metadata: + json_metadata['roles'] = ([x['id'] for x in json_metadata['roles'] + if 'inherited_to' not in x]) + return json.dumps(json_metadata) + + downgrade_table = sql.Table(table_name, meta, autoload=True) + for assignment in session.query(downgrade_table): + values = {'data': dict_list_to_list(assignment.data)} + update = build_update(table_name, downgrade_table, assignment, values) + migrate_engine.execute(update) + + +def upgrade(migrate_engine): + meta = sql.MetaData() + meta.bind = migrate_engine + session = sql.orm.sessionmaker(bind=migrate_engine)() + + for grant_table in ['user_project_metadata', 'user_domain_metadata', + 'group_project_metadata', 'group_domain_metadata']: + upgrade_grant_table(meta, migrate_engine, session, grant_table) + session.commit() + session.close() + + +def downgrade(migrate_engine): + meta = sql.MetaData() + meta.bind = migrate_engine + session = sql.orm.sessionmaker(bind=migrate_engine)() + + for grant_table in ['user_project_metadata', 'user_domain_metadata', + 'group_project_metadata', 'group_domain_metadata']: + downgrade_grant_table(meta, migrate_engine, session, grant_table) + session.commit() + session.close() diff --git a/keystone/common/sql/migrate_repo/versions/030_drop_credential_constraint_sqlite.py b/keystone/common/sql/migrate_repo/versions/030_drop_credential_constraint_sqlite.py new file mode 100644 index 00000000..27676dcc --- /dev/null +++ b/keystone/common/sql/migrate_repo/versions/030_drop_credential_constraint_sqlite.py @@ -0,0 +1,119 @@ + +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 OpenStack LLC +# +# 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 sqlalchemy +from sqlalchemy.orm import sessionmaker + + +def upgrade(migrate_engine): + if migrate_engine.name == 'sqlite': + drop_credential_table_foreign_key_constraints_for_sqlite( + migrate_engine) + + +def downgrade(migrate_engine): + if migrate_engine.name == 'sqlite': + add_credential_table_foreign_key_constraints_for_sqlite(migrate_engine) + + +def drop_credential_table_foreign_key_constraints_for_sqlite(migrate_engine): + meta = sqlalchemy.MetaData() + meta.bind = migrate_engine + + # NOTE(nachiappan): SQLite does not support ALTER TABLE DROP constraint. + # So we need to move the data to new credenital table + # created without constraints, drop the old table and + # rename the new table to credential. + sqlalchemy.Table('user', meta, autoload=True) + tenant_table = sqlalchemy.Table( + 'tenant', + meta, + sqlalchemy.Column('id', sqlalchemy.String(64), primary_key=True), + sqlalchemy.Column( + 'name', sqlalchemy.String(64), unique=True, nullable=False), + sqlalchemy.Column('extra', sqlalchemy.Text())) + tenant_table.create(migrate_engine, checkfirst=True) + cred_table = sqlalchemy.Table('credential', meta, autoload=True) + + session = sessionmaker(bind=migrate_engine)() + new_credential_table = sqlalchemy.Table( + 'new_credential', + meta, + sqlalchemy.Column('id', sqlalchemy.String(64), primary_key=True), + sqlalchemy.Column('user_id', + sqlalchemy.String(64), + nullable=False), + sqlalchemy.Column('project_id', + sqlalchemy.String(64)), + sqlalchemy.Column('blob', sqlalchemy.Text(), nullable=False), + sqlalchemy.Column('type', sqlalchemy.String(255), nullable=False), + sqlalchemy.Column('extra', sqlalchemy.Text())) + new_credential_table.create(migrate_engine, checkfirst=True) + + insert = new_credential_table.insert() + for credential in session.query(cred_table): + insert.execute({'id': credential.id, + 'user_id': credential.user_id, + 'project_id': credential.project_id, + 'blob': credential.blob, + 'type': credential.type, + 'extra': credential.extra}) + cred_table.drop() + tenant_table.drop() + new_credential_table.rename('credential') + session.commit() + session.close() + + +def add_credential_table_foreign_key_constraints_for_sqlite(migrate_engine): + meta = sqlalchemy.MetaData() + meta.bind = migrate_engine + + cred_table = sqlalchemy.Table('credential', meta, autoload=True) + sqlalchemy.Table('user', meta, autoload=True) + + session = sessionmaker(bind=migrate_engine)() + old_credential_table = sqlalchemy.Table( + 'old_credential', + meta, + sqlalchemy.Column('id', sqlalchemy.String(64), primary_key=True), + sqlalchemy.Column('user_id', + sqlalchemy.String(64), + sqlalchemy.ForeignKey('user.id'), + nullable=False), + # NOTE(nachiappan): Not creating the foreign key constraint with + # project table as version 15 conflicts with + # version 7. + sqlalchemy.Column('project_id', + sqlalchemy.String(64)), + sqlalchemy.Column('blob', sqlalchemy.Text(), nullable=False), + sqlalchemy.Column('type', sqlalchemy.String(255), nullable=False), + sqlalchemy.Column('extra', sqlalchemy.Text())) + old_credential_table.create(migrate_engine, checkfirst=True) + + insert = old_credential_table.insert() + for credential in session.query(cred_table): + insert.execute({'id': credential.id, + 'user_id': credential.user_id, + 'project_id': credential.project_id, + 'blob': credential.blob, + 'type': credential.type, + 'extra': credential.extra}) + cred_table.drop() + old_credential_table.rename('credential') + session.commit() + session.close() diff --git a/keystone/common/sql/migration_helpers.py b/keystone/common/sql/migration_helpers.py index 6823b6a7..8a581924 100644 --- a/keystone/common/sql/migration_helpers.py +++ b/keystone/common/sql/migration_helpers.py @@ -52,7 +52,44 @@ def remove_constraints(constraints): def add_constraints(constraints): for constraint_def in constraints: + + if constraint_def['table'].kwargs.get('mysql_engine') == 'MyISAM': + # Don't try to create constraint when using MyISAM because it's + # not supported. + continue + + ref_col = constraint_def['ref_column'] + ref_engine = ref_col.table.kwargs.get('mysql_engine') + if ref_engine == 'MyISAM': + # Don't try to create constraint when using MyISAM because it's + # not supported. + continue + migrate.ForeignKeyConstraint( columns=[getattr(constraint_def['table'].c, constraint_def['fk_column'])], refcolumns=[constraint_def['ref_column']]).create() + + +def rename_tables_with_constraints(renames, constraints, engine): + """Renames tables with foreign key constraints. + + Tables are renamed after first removing constraints. The constraints are + replaced after the rename is complete. + + This works on databases that don't support renaming tables that have + constraints on them (DB2). + + `renames` is a dict, mapping {'to_table_name': from_table, ...} + """ + + if engine.name != 'sqlite': + # Sqlite doesn't support constraints, so nothing to remove. + remove_constraints(constraints) + + for to_table_name in renames: + from_table = renames[to_table_name] + from_table.rename(to_table_name) + + if engine != 'sqlite': + add_constraints(constraints) diff --git a/keystone/common/sql/nova.py b/keystone/common/sql/nova.py index c6d452cd..fd8d2481 100644 --- a/keystone/common/sql/nova.py +++ b/keystone/common/sql/nova.py @@ -18,10 +18,11 @@ import uuid +from keystone import assignment from keystone.common import logging from keystone import config from keystone.contrib.ec2.backends import sql as ec2_sql -from keystone.identity.backends import sql as identity_sql +from keystone import identity LOG = logging.getLogger(__name__) @@ -30,18 +31,20 @@ DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id def import_auth(data): - identity_api = identity_sql.Identity() - tenant_map = _create_projects(identity_api, data['tenants']) + identity_api = identity.Manager() + assignment_api = assignment.Manager() + + tenant_map = _create_projects(assignment_api, data['tenants']) user_map = _create_users(identity_api, data['users']) - _create_memberships(identity_api, data['user_tenant_list'], + _create_memberships(assignment_api, data['user_tenant_list'], user_map, tenant_map) - role_map = _create_roles(identity_api, data['roles']) - _assign_roles(identity_api, data['role_user_tenant_list'], + role_map = _create_roles(assignment_api, data['roles']) + _assign_roles(assignment_api, data['role_user_tenant_list'], role_map, user_map, tenant_map) ec2_api = ec2_sql.Ec2() ec2_creds = data['ec2_credentials'] - _create_ec2_creds(ec2_api, identity_api, ec2_creds, user_map) + _create_ec2_creds(ec2_api, assignment_api, ec2_creds, user_map) def _generate_uuid(): @@ -120,10 +123,10 @@ def _assign_roles(api, assignments, role_map, user_map, tenant_map): api.add_role_to_user_and_project(user_id, tenant_id, role_id) -def _create_ec2_creds(ec2_api, identity_api, ec2_creds, user_map): +def _create_ec2_creds(ec2_api, assignment_api, ec2_creds, user_map): for ec2_cred in ec2_creds: user_id = user_map[ec2_cred['user_id']] - for tenant_id in identity_api.get_projects_for_user(user_id): + for tenant_id in assignment_api.get_projects_for_user(user_id): cred_dict = { 'access': '%s:%s' % (tenant_id, ec2_cred['access_key']), 'secret': ec2_cred['secret_key'], diff --git a/keystone/common/sql/util.py b/keystone/common/sql/util.py deleted file mode 100644 index c31e50c0..00000000 --- a/keystone/common/sql/util.py +++ /dev/null @@ -1,42 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import shutil - -from keystone.common.sql import core -from keystone.common.sql import migration -from keystone import config - - -CONF = config.CONF - - -def setup_test_database(): - try: - if os.path.exists('test.db'): - os.unlink('test.db') - if not os.path.exists('test.db.pristine'): - migration.db_sync() - shutil.copyfile('test.db', 'test.db.pristine') - else: - shutil.copyfile('test.db.pristine', 'test.db') - except Exception: - pass - - -def teardown_test_database(): - core.set_global_engine(None) diff --git a/keystone/common/wsgi.py b/keystone/common/wsgi.py index 5143db6e..f47cde13 100644 --- a/keystone/common/wsgi.py +++ b/keystone/common/wsgi.py @@ -73,6 +73,55 @@ def mask_password(message, is_unicode=False, secret="***"): return result +def validate_token_bind(context, token_ref): + bind_mode = CONF.token.enforce_token_bind + + if bind_mode == 'disabled': + return + + bind = token_ref.get('bind', {}) + + # permissive and strict modes don't require there to be a bind + permissive = bind_mode in ('permissive', 'strict') + + # get the named mode if bind_mode is not one of the known + name = None if permissive or bind_mode == 'required' else bind_mode + + if not bind: + if permissive: + # no bind provided and none required + return + else: + LOG.info(_("No bind information present in token")) + raise exception.Unauthorized() + + if name and name not in bind: + LOG.info(_("Named bind mode %s not in bind information"), name) + raise exception.Unauthorized() + + for bind_type, identifier in bind.iteritems(): + if bind_type == 'kerberos': + if not context.get('AUTH_TYPE', '').lower() == 'negotiate': + LOG.info(_("Kerberos credentials required and not present")) + raise exception.Unauthorized() + + if not context.get('REMOTE_USER') == identifier: + LOG.info(_("Kerberos credentials do not match those in bind")) + raise exception.Unauthorized() + + LOG.info(_("Kerberos bind authentication successful")) + + elif bind_mode == 'permissive': + LOG.debug(_("Ignoring unknown bind for permissive mode: " + "{%(bind_type)s: %(identifier)s}"), + {'bind_type': bind_type, 'identifier': identifier}) + else: + LOG.info(_("Couldn't verify unknown bind: " + "{%(bind_type)s: %(identifier)s}"), + {'bind_type': bind_type, 'identifier': identifier}) + raise exception.Unauthorized() + + class WritableLogger(object): """A thin wrapper that responds to `write` and logs.""" @@ -103,18 +152,18 @@ class BaseApplication(object): [app:wadl] latest_version = 1.3 - paste.app_factory = nova.api.fancy_api:Wadl.factory + paste.app_factory = keystone.fancy_api:Wadl.factory which would result in a call to the `Wadl` class as - import nova.api.fancy_api - fancy_api.Wadl(latest_version='1.3') + import keystone.fancy_api + keystone.fancy_api.Wadl(latest_version='1.3') You could of course re-implement the `factory` method in subclasses, but using the kwarg passing it shouldn't be necessary. """ - return cls() + return cls(**local_config) def __call__(self, environ, start_response): r"""Subclasses will probably want to implement __call__ like this: @@ -154,7 +203,7 @@ class BaseApplication(object): class Application(BaseApplication): - @webob.dec.wsgify + @webob.dec.wsgify(RequestClass=Request) def __call__(self, req): arg_dict = req.environ['wsgiorg.routing_args'][1] action = arg_dict.pop('action') @@ -167,12 +216,20 @@ class Application(BaseApplication): context['headers'] = dict(req.headers.iteritems()) context['path'] = req.environ['PATH_INFO'] params = req.environ.get(PARAMS_ENV, {}) - if 'REMOTE_USER' in req.environ: - context['REMOTE_USER'] = req.environ['REMOTE_USER'] - elif context.get('REMOTE_USER', None) is not None: - del context['REMOTE_USER'] + + for name in ['REMOTE_USER', 'AUTH_TYPE']: + try: + context[name] = req.environ[name] + except KeyError: + try: + del context[name] + except KeyError: + pass + params.update(arg_dict) + context.setdefault('is_admin', False) + # TODO(termie): do some basic normalization on methods method = getattr(self, action) @@ -226,11 +283,11 @@ class Application(BaseApplication): def assert_admin(self, context): if not context['is_admin']: try: - user_token_ref = self.token_api.get_token( - token_id=context['token_id']) + user_token_ref = self.token_api.get_token(context['token_id']) except exception.TokenNotFound as e: raise exception.Unauthorized(e) + validate_token_bind(context, user_token_ref) creds = user_token_ref['metadata'].copy() try: @@ -274,12 +331,12 @@ class Middleware(Application): [filter:analytics] redis_host = 127.0.0.1 - paste.filter_factory = nova.api.analytics:Analytics.factory + paste.filter_factory = keystone.analytics:Analytics.factory which would result in a call to the `Analytics` class as - import nova.api.analytics - analytics.Analytics(app_from_paste, redis_host='127.0.0.1') + import keystone.analytics + keystone.analytics.Analytics(app, redis_host='127.0.0.1') You could of course re-implement the `factory` method in subclasses, but using the kwarg passing it shouldn't be necessary. @@ -484,12 +541,12 @@ class ExtensionRouter(Router): [filter:analytics] redis_host = 127.0.0.1 - paste.filter_factory = nova.api.analytics:Analytics.factory + paste.filter_factory = keystone.analytics:Analytics.factory which would result in a call to the `Analytics` class as - import nova.api.analytics - analytics.Analytics(app_from_paste, redis_host='127.0.0.1') + import keystone.analytics + keystone.analytics.Analytics(app, redis_host='127.0.0.1') You could of course re-implement the `factory` method in subclasses, but using the kwarg passing it shouldn't be necessary. @@ -498,7 +555,7 @@ class ExtensionRouter(Router): def _factory(app): conf = global_config.copy() conf.update(local_config) - return cls(app) + return cls(app, **local_config) return _factory @@ -525,7 +582,7 @@ def render_exception(error): body = {'error': { 'code': error.code, 'title': error.title, - 'message': str(error) + 'message': unicode(error) }} if isinstance(error, exception.AuthPluginException): body['error']['identity'] = error.authentication diff --git a/keystone/contrib/admin_crud/core.py b/keystone/contrib/admin_crud/core.py index c06afcf7..f98397ae 100644 --- a/keystone/contrib/admin_crud/core.py +++ b/keystone/contrib/admin_crud/core.py @@ -14,10 +14,31 @@ # License for the specific language governing permissions and limitations # under the License. from keystone import catalog +from keystone.common import extension from keystone.common import wsgi from keystone import identity +extension.register_admin_extension( + 'OS-KSADM', { + 'name': 'OpenStack Keystone Admin', + 'namespace': 'http://docs.openstack.org/identity/api/ext/' + 'OS-KSADM/v1.0', + 'alias': 'OS-KSADM', + 'updated': '2013-07-11T17:14:00-00:00', + 'description': 'OpenStack extensions to Keystone v2.0 API ' + 'enabling Administrative Operations.', + 'links': [ + { + 'rel': 'describedby', + # TODO(dolph): link needs to be revised after + # bug 928059 merges + 'type': 'text/html', + 'href': 'https://github.com/openstack/identity-api', + } + ]}) + + class CrudExtension(wsgi.ExtensionRouter): """Previously known as the OS-KSADM extension. diff --git a/keystone/contrib/ec2/core.py b/keystone/contrib/ec2/core.py index e8471ec6..8f72e431 100644 --- a/keystone/contrib/ec2/core.py +++ b/keystone/contrib/ec2/core.py @@ -40,6 +40,7 @@ from keystoneclient.contrib.ec2 import utils as ec2_utils from keystone.common import controller from keystone.common import dependency +from keystone.common import extension from keystone.common import manager from keystone.common import utils from keystone.common import wsgi @@ -51,6 +52,25 @@ from keystone import token CONF = config.CONF +EXTENSION_DATA = { + 'name': 'OpenStack EC2 API', + 'namespace': 'http://docs.openstack.org/identity/api/ext/' + 'OS-EC2/v1.0', + 'alias': 'OS-EC2', + 'updated': '2013-07-07T12:00:0-00:00', + 'description': 'OpenStack EC2 Credentials backend.', + 'links': [ + { + 'rel': 'describedby', + # TODO(ayoung): needs a description + 'type': 'text/html', + 'href': 'https://github.com/openstack/identity-api', + } + ]} +extension.register_admin_extension(EXTENSION_DATA['alias'], EXTENSION_DATA) +extension.register_public_extension(EXTENSION_DATA['alias'], EXTENSION_DATA) + + @dependency.provider('ec2_api') class Manager(manager.Manager): """Default pivot point for the EC2 Credentials backend. @@ -97,7 +117,7 @@ class Ec2Extension(wsgi.ExtensionRouter): conditions=dict(method=['DELETE'])) -@dependency.requires('catalog_api', 'ec2_api') +@dependency.requires('catalog_api', 'ec2_api', 'token_provider_api') class Ec2Controller(controller.V2Controller): def check_signature(self, creds_ref, credentials): signer = ec2_utils.Ec2Signer(creds_ref['secret']) @@ -153,16 +173,14 @@ class Ec2Controller(controller.V2Controller): token_id = uuid.uuid4().hex tenant_ref = self.identity_api.get_project(creds_ref['tenant_id']) user_ref = self.identity_api.get_user(creds_ref['user_id']) - metadata_ref = self.identity_api.get_metadata( - user_id=user_ref['id'], - tenant_id=tenant_ref['id']) + metadata_ref = {} + metadata_ref['roles'] = ( + self.identity_api.get_roles_for_user_and_project( + user_ref['id'], tenant_ref['id'])) # Validate that the auth info is valid and nothing is disabled token.validate_auth_info(self, user_ref, tenant_ref) - # TODO(termie): optimize this call at some point and put it into the - # the return for metadata - # fill out the roles in the metadata roles = metadata_ref.get('roles', []) if not roles: raise exception.Unauthorized(message='User not valid for tenant.') @@ -170,21 +188,18 @@ class Ec2Controller(controller.V2Controller): for role_id in roles] catalog_ref = self.catalog_api.get_catalog( - user_id=user_ref['id'], - tenant_id=tenant_ref['id'], - metadata=metadata_ref) - - token_ref = self.token_api.create_token( - token_id, dict(id=token_id, - user=user_ref, - tenant=tenant_ref, - metadata=metadata_ref)) - - # TODO(termie): i don't think the ec2 middleware currently expects a - # full return, but it contains a note saying that it - # would be better to expect a full return - return token.controllers.Auth.format_authenticate( - token_ref, roles_ref, catalog_ref) + user_ref['id'], tenant_ref['id'], metadata_ref) + + auth_token_data = dict(user=user_ref, + tenant=tenant_ref, + metadata=metadata_ref, + id='placeholder') + (token_id, token_data) = self.token_provider_api.issue_token( + version=token.provider.V2, + token_ref=auth_token_data, + roles_ref=roles_ref, + catalog_ref=catalog_ref) + return token_data def create_credential(self, context, user_id, tenant_id): """Create a secret/access pair for use with ec2 style auth. diff --git a/keystone/contrib/s3/core.py b/keystone/contrib/s3/core.py index 44b038d4..29ea4fe2 100644 --- a/keystone/contrib/s3/core.py +++ b/keystone/contrib/s3/core.py @@ -27,6 +27,7 @@ import base64 import hashlib import hmac +from keystone.common import extension from keystone.common import utils from keystone.common import wsgi from keystone import config @@ -35,6 +36,23 @@ from keystone import exception CONF = config.CONF +EXTENSION_DATA = { + 'name': 'OpenStack S3 API', + 'namespace': 'http://docs.openstack.org/identity/api/ext/' + 's3tokens/v1.0', + 'alias': 's3tokens', + 'updated': '2013-07-07T12:00:0-00:00', + 'description': 'OpenStack S3 API.', + 'links': [ + { + 'rel': 'describedby', + # TODO(ayoung): needs a description + 'type': 'text/html', + 'href': 'https://github.com/openstack/identity-api', + } + ]} +extension.register_admin_extension(EXTENSION_DATA['alias'], EXTENSION_DATA) + class S3Extension(wsgi.ExtensionRouter): def add_routes(self, mapper): diff --git a/keystone/contrib/stats/core.py b/keystone/contrib/stats/core.py index 0325c4fa..1d7b2cdf 100644 --- a/keystone/contrib/stats/core.py +++ b/keystone/contrib/stats/core.py @@ -14,6 +14,7 @@ # License for the specific language governing permissions and limitations # under the License. +from keystone.common import extension from keystone.common import logging from keystone.common import manager from keystone.common import wsgi @@ -27,6 +28,23 @@ from keystone import token CONF = config.CONF LOG = logging.getLogger(__name__) +extension_data = { + 'name': 'Openstack Keystone Stats API', + 'namespace': 'http://docs.openstack.org/identity/api/ext/' + 'OS-STATS/v1.0', + 'alias': 'OS-STATS', + 'updated': '2013-07-07T12:00:0-00:00', + 'description': 'Openstack Keystone Stats API.', + 'links': [ + { + 'rel': 'describedby', + # TODO(ayoung): needs a description + 'type': 'text/html', + 'href': 'https://github.com/openstack/identity-api', + } + ]} +extension.register_admin_extension(extension_data['alias'], extension_data) + class Manager(manager.Manager): """Default pivot point for the Stats backend. diff --git a/keystone/contrib/user_crud/core.py b/keystone/contrib/user_crud/core.py index 79144ae5..f9f09b89 100644 --- a/keystone/contrib/user_crud/core.py +++ b/keystone/contrib/user_crud/core.py @@ -17,6 +17,7 @@ import copy import uuid +from keystone.common import extension from keystone.common import logging from keystone.common import wsgi from keystone import exception @@ -26,6 +27,25 @@ from keystone import identity LOG = logging.getLogger(__name__) +extension.register_public_extension( + 'OS-KSCRUD', { + 'name': 'OpenStack Keystone User CRUD', + 'namespace': 'http://docs.openstack.org/identity/api/ext/' + 'OS-KSCRUD/v1.0', + 'alias': 'OS-KSCRUD', + 'updated': '2013-07-07T12:00:0-00:00', + 'description': 'OpenStack extensions to Keystone v2.0 API ' + 'enabling User Operations.', + 'links': [ + { + 'rel': 'describedby', + # TODO(ayoung): needs a description + 'type': 'text/html', + 'href': 'https://github.com/openstack/identity-api', + } + ]}) + + class UserController(identity.controllers.User): def set_user_password(self, context, user_id, user): token_id = context.get('token_id') @@ -43,7 +63,7 @@ class UserController(identity.controllers.User): try: user_ref = self.identity_api.authenticate( user_id=user_id_from_token, - password=original_password)[0] + password=original_password) if not user_ref.get('enabled', True): # NOTE(dolph): why can't you set a disabled user's password? raise exception.Unauthorized('User is disabled') diff --git a/keystone/controllers.py b/keystone/controllers.py index 6dd303e1..8ffa073a 100644 --- a/keystone/controllers.py +++ b/keystone/controllers.py @@ -14,6 +14,7 @@ # License for the specific language governing permissions and limitations # under the License. +from keystone.common import extension from keystone.common import logging from keystone.common import wsgi from keystone import config @@ -32,10 +33,10 @@ _VERSIONS = [] class Extensions(wsgi.Application): """Base extensions controller to be extended by public and admin API's.""" - def __init__(self, extensions=None): - super(Extensions, self).__init__() - - self.extensions = extensions or {} + #extend in subclass to specify the set of extensions + @property + def extensions(self): + return None def get_extensions_info(self, context): return {'extensions': {'values': self.extensions.values()}} @@ -48,34 +49,15 @@ class Extensions(wsgi.Application): class AdminExtensions(Extensions): - def __init__(self, *args, **kwargs): - super(AdminExtensions, self).__init__(*args, **kwargs) - - # TODO(dolph): Extensions should obviously provide this information - # themselves, but hardcoding it here allows us to match - # the API spec in the short term with minimal complexity. - self.extensions['OS-KSADM'] = { - 'name': 'Openstack Keystone Admin', - 'namespace': 'http://docs.openstack.org/identity/api/ext/' - 'OS-KSADM/v1.0', - 'alias': 'OS-KSADM', - 'updated': '2011-08-19T13:25:27-06:00', - 'description': 'Openstack extensions to Keystone v2.0 API ' - 'enabling Admin Operations.', - 'links': [ - { - 'rel': 'describedby', - # TODO(dolph): link needs to be revised after - # bug 928059 merges - 'type': 'text/html', - 'href': 'https://github.com/openstack/identity-api', - } - ] - } + @property + def extensions(self): + return extension.ADMIN_EXTENSIONS class PublicExtensions(Extensions): - pass + @property + def extensions(self): + return extension.PUBLIC_EXTENSIONS def register_version(version): diff --git a/keystone/exception.py b/keystone/exception.py index db5f5005..5e1defba 100644 --- a/keystone/exception.py +++ b/keystone/exception.py @@ -13,10 +13,10 @@ # 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 re from keystone.common import config from keystone.common import logging +from keystone.openstack.common.gettextutils import _ # noqa CONF = config.CONF @@ -29,15 +29,15 @@ _FATAL_EXCEPTION_FORMAT_ERRORS = False class Error(StandardError): """Base error class. - Child classes should define an HTTP status code, title, and a doc string. + Child classes should define an HTTP status code, title, and a + message_format. """ code = None title = None + message_format = None def __init__(self, message=None, **kwargs): - """Use the doc string as the error message by default.""" - try: message = self._build_message(message, **kwargs) except KeyError: @@ -45,8 +45,8 @@ class Error(StandardError): if _FATAL_EXCEPTION_FORMAT_ERRORS: raise else: - LOG.warning('missing exception kwargs (programmer error)') - message = self.__doc__ + LOG.warning(_('missing exception kwargs (programmer error)')) + message = self.message_format super(Error, self).__init__(message) @@ -57,42 +57,31 @@ class Error(StandardError): """ if not message: - message = re.sub('[ \n]+', ' ', self.__doc__ % kwargs) - message = message.strip() + message = self.message_format % kwargs return message class ValidationError(Error): - """Expecting to find %(attribute)s in %(target)s. - - The server could not comply with the request since it is either malformed - or otherwise incorrect. - - The client is assumed to be in error. - - """ + message_format = _("Expecting to find %(attribute)s in %(target)s." + " The server could not comply with the request" + " since it is either malformed or otherwise" + " incorrect. The client is assumed to be in error.") code = 400 title = 'Bad Request' class StringLengthExceeded(ValidationError): - """String length exceeded. - - The length of string "%(string)s" exceeded the limit of column - %(type)s(CHAR(%(length)d)). - - """ + message_format = _("String length exceeded.The length of" + " string '%(string)s' exceeded the limit" + " of column %(type)s(CHAR(%(length)d)).") class ValidationSizeError(Error): - """Request attribute %(attribute)s must be less than or equal to %(size)i. - - The server could not comply with the request because the attribute - size is invalid (too large). - - The client is assumed to be in error. - - """ + message_format = _("Request attribute %(attribute)s must be" + " less than or equal to %(size)i. The server" + " could not comply with the request because" + " the attribute size is invalid (too large)." + " The client is assumed to be in error.") code = 400 title = 'Bad Request' @@ -103,19 +92,19 @@ class SecurityError(Error): def _build_message(self, message, **kwargs): """Only returns detailed messages in debug mode.""" if CONF.debug: - return message or self.__doc__ % kwargs + return message or self.message_format % kwargs else: - return self.__doc__ % kwargs + return self.message_format % kwargs class Unauthorized(SecurityError): - """The request you have made requires authentication.""" + message_format = _("The request you have made requires authentication.") code = 401 title = 'Unauthorized' class AuthPluginException(Unauthorized): - """Authentication plugin error.""" + message_format = _("Authentication plugin error.") def __init__(self, *args, **kwargs): super(AuthPluginException, self).__init__(*args, **kwargs) @@ -123,7 +112,7 @@ class AuthPluginException(Unauthorized): class AuthMethodNotSupported(AuthPluginException): - """Attempted to authenticate with an unsupported method.""" + message_format = _("Attempted to authenticate with an unsupported method.") def __init__(self, *args, **kwargs): super(AuthMethodNotSupported, self).__init__(*args, **kwargs) @@ -131,7 +120,7 @@ class AuthMethodNotSupported(AuthPluginException): class AdditionalAuthRequired(AuthPluginException): - """Additional authentications steps required.""" + message_format = _("Additional authentications steps required.") def __init__(self, auth_response=None, **kwargs): super(AdditionalAuthRequired, self).__init__(message=None, **kwargs) @@ -139,112 +128,111 @@ class AdditionalAuthRequired(AuthPluginException): class Forbidden(SecurityError): - """You are not authorized to perform the requested action.""" + message_format = _("You are not authorized to perform the" + " requested action.") code = 403 title = 'Forbidden' class ForbiddenAction(Forbidden): - """You are not authorized to perform the requested action, %(action)s.""" + message_format = _("You are not authorized to perform the" + " requested action, %(action)s.") class NotFound(Error): - """Could not find, %(target)s.""" + message_format = _("Could not find, %(target)s.") code = 404 title = 'Not Found' class EndpointNotFound(NotFound): - """Could not find endpoint, %(endpoint_id)s.""" + message_format = _("Could not find endpoint, %(endpoint_id)s.") class MetadataNotFound(NotFound): - """An unhandled exception has occurred: Could not find metadata.""" - # (dolph): metadata is not a user-facing concept, - # so this exception should not be exposed + """(dolph): metadata is not a user-facing concept, + so this exception should not be exposed + """ + message_format = _("An unhandled exception has occurred:" + " Could not find metadata.") class PolicyNotFound(NotFound): - """Could not find policy, %(policy_id)s.""" + message_format = _("Could not find policy, %(policy_id)s.") class RoleNotFound(NotFound): - """Could not find role, %(role_id)s.""" + message_format = _("Could not find role, %(role_id)s.") class ServiceNotFound(NotFound): - """Could not find service, %(service_id)s.""" + message_format = _("Could not find service, %(service_id)s.") class DomainNotFound(NotFound): - """Could not find domain, %(domain_id)s.""" + message_format = _("Could not find domain, %(domain_id)s.") class ProjectNotFound(NotFound): - """Could not find project, %(project_id)s.""" + message_format = _("Could not find project, %(project_id)s.") class TokenNotFound(NotFound): - """Could not find token, %(token_id)s.""" + message_format = _("Could not find token, %(token_id)s.") class UserNotFound(NotFound): - """Could not find user, %(user_id)s.""" + message_format = _("Could not find user, %(user_id)s.") class GroupNotFound(NotFound): - """Could not find group, %(group_id)s.""" + message_format = _("Could not find group, %(group_id)s.") class TrustNotFound(NotFound): - """Could not find trust, %(trust_id)s.""" + message_format = _("Could not find trust, %(trust_id)s.") class CredentialNotFound(NotFound): - """Could not find credential, %(credential_id)s.""" + message_format = _("Could not find credential, %(credential_id)s.") class VersionNotFound(NotFound): - """Could not find version, %(version)s.""" + message_format = _("Could not find version, %(version)s.") class Conflict(Error): - """Conflict occurred attempting to store %(type)s. - - %(details)s - - """ + message_format = _("Conflict occurred attempting to store %(type)s." + " %(details)s") code = 409 title = 'Conflict' class RequestTooLarge(Error): - """Request is too large.""" + message_format = _("Request is too large.") code = 413 title = 'Request is too large.' class UnexpectedError(Error): - """An unexpected error prevented the server from fulfilling your request. - - %(exception)s - - """ + message_format = _("An unexpected error prevented the server" + " from fulfilling your request. %(exception)s") code = 500 title = 'Internal Server Error' class MalformedEndpoint(UnexpectedError): - """Malformed endpoint URL (%(endpoint)s), see ERROR log for details.""" + message_format = _("Malformed endpoint URL (%(endpoint)s)," + " see ERROR log for details.") class NotImplemented(Error): - """The action you have requested has not been implemented.""" + message_format = _("The action you have requested has not" + " been implemented.") code = 501 title = 'Not Implemented' class PasteConfigNotFound(UnexpectedError): - """The Keystone paste configuration file %(config_file)s could not be - found. - """ + message_format = _("The Keystone paste configuration file" + " %(config_file)s could not be found.") diff --git a/keystone/identity/backends/kvs.py b/keystone/identity/backends/kvs.py index 2eea08cf..0323d3d0 100644 --- a/keystone/identity/backends/kvs.py +++ b/keystone/identity/backends/kvs.py @@ -14,7 +14,6 @@ # License for the specific language governing permissions and limitations # under the License. -from keystone import clean from keystone.common import kvs from keystone.common import utils from keystone import exception @@ -22,8 +21,14 @@ from keystone import identity class Identity(kvs.Base, identity.Driver): + def __init__(self): + super(Identity, self).__init__() + + def default_assignment_driver(self): + return "keystone.assignment.backends.kvs.Assignment" + # Public interface - def authenticate_user(self, user_id=None, password=None): + def authenticate(self, user_id, password): user_ref = None try: user_ref = self._get_user(user_id) @@ -31,48 +36,7 @@ class Identity(kvs.Base, identity.Driver): raise AssertionError('Invalid user / password') if not utils.check_password(password, user_ref.get('password')): raise AssertionError('Invalid user / password') - return user_ref - - def authorize_for_project(self, user_ref, tenant_id=None): - user_id = user_ref['id'] - tenant_ref = None - metadata_ref = {} - if tenant_id is not None: - if tenant_id not in self.get_projects_for_user(user_id): - raise AssertionError('Invalid tenant') - try: - tenant_ref = self.get_project(tenant_id) - metadata_ref = self.get_metadata(user_id, tenant_id) - except exception.ProjectNotFound: - tenant_ref = None - metadata_ref = {} - except exception.MetadataNotFound: - metadata_ref = {} - return (identity.filter_user(user_ref), tenant_ref, metadata_ref) - - def get_project(self, tenant_id): - try: - return self.db.get('tenant-%s' % tenant_id) - except exception.NotFound: - raise exception.ProjectNotFound(project_id=tenant_id) - - def list_projects(self): - tenant_keys = filter(lambda x: x.startswith("tenant-"), - self.db.keys()) - return [self.db.get(key) for key in tenant_keys] - - def get_project_by_name(self, tenant_name, domain_id): - try: - return self.db.get('tenant_name-%s' % tenant_name) - except exception.NotFound: - raise exception.ProjectNotFound(project_id=tenant_name) - - def get_project_users(self, tenant_id): - self.get_project(tenant_id) - user_keys = filter(lambda x: x.startswith("user-"), self.db.keys()) - user_refs = [self.db.get(key) for key in user_keys] - user_refs = filter(lambda x: tenant_id in x['tenants'], user_refs) - return [identity.filter_user(user_ref) for user_ref in user_refs] + return identity.filter_user(user_ref) def _get_user(self, user_id): try: @@ -93,93 +57,10 @@ class Identity(kvs.Base, identity.Driver): return identity.filter_user( self._get_user_by_name(user_name, domain_id)) - def get_metadata(self, user_id=None, tenant_id=None, - domain_id=None, group_id=None): - try: - if user_id: - if tenant_id: - return self.db.get('metadata-%s-%s' % (tenant_id, - user_id)) - else: - return self.db.get('metadata-%s-%s' % (domain_id, - user_id)) - else: - if tenant_id: - return self.db.get('metadata-%s-%s' % (tenant_id, - group_id)) - else: - return self.db.get('metadata-%s-%s' % (domain_id, - group_id)) - except exception.NotFound: - raise exception.MetadataNotFound() - - def get_role(self, role_id): - try: - return self.db.get('role-%s' % role_id) - except exception.NotFound: - raise exception.RoleNotFound(role_id=role_id) - def list_users(self): user_ids = self.db.get('user_list', []) return [self.get_user(x) for x in user_ids] - def list_roles(self): - role_ids = self.db.get('role_list', []) - return [self.get_role(x) for x in role_ids] - - def get_projects_for_user(self, user_id): - user_ref = self._get_user(user_id) - return user_ref.get('tenants', []) - - def get_roles_for_user_and_project(self, user_id, tenant_id): - self.get_user(user_id) - self.get_project(tenant_id) - try: - metadata_ref = self.get_metadata(user_id, tenant_id) - except exception.MetadataNotFound: - metadata_ref = {} - return metadata_ref.get('roles', []) - - def add_role_to_user_and_project(self, user_id, tenant_id, role_id): - self.get_user(user_id) - self.get_project(tenant_id) - self.get_role(role_id) - try: - metadata_ref = self.get_metadata(user_id, tenant_id) - except exception.MetadataNotFound: - metadata_ref = {} - roles = set(metadata_ref.get('roles', [])) - if role_id in roles: - msg = ('User %s already has role %s in tenant %s' - % (user_id, role_id, tenant_id)) - raise exception.Conflict(type='role grant', details=msg) - roles.add(role_id) - metadata_ref['roles'] = list(roles) - self.update_metadata(user_id, tenant_id, metadata_ref) - - def remove_role_from_user_and_project(self, user_id, tenant_id, role_id): - try: - metadata_ref = self.get_metadata(user_id, tenant_id) - except exception.MetadataNotFound: - metadata_ref = {} - roles = set(metadata_ref.get('roles', [])) - if role_id not in roles: - msg = 'Cannot remove role that has not been granted, %s' % role_id - raise exception.RoleNotFound(message=msg) - - roles.remove(role_id) - metadata_ref['roles'] = list(roles) - - if not len(roles): - self.db.delete('metadata-%s-%s' % (tenant_id, user_id)) - user_ref = self._get_user(user_id) - tenants = set(user_ref.get('tenants', [])) - tenants.remove(tenant_id) - user_ref['tenants'] = list(tenants) - self.update_user(user_id, user_ref) - else: - self.update_metadata(user_id, tenant_id, metadata_ref) - # CRUD def create_user(self, user_id, user): try: @@ -278,301 +159,6 @@ class Identity(kvs.Base, identity.Driver): user_list.remove(user_id) self.db.set('user_list', list(user_list)) - def create_project(self, tenant_id, tenant): - tenant['name'] = clean.project_name(tenant['name']) - try: - self.get_project(tenant_id) - except exception.ProjectNotFound: - pass - else: - msg = 'Duplicate ID, %s.' % tenant_id - raise exception.Conflict(type='tenant', details=msg) - - try: - self.get_project_by_name(tenant['name'], tenant['domain_id']) - except exception.ProjectNotFound: - pass - else: - msg = 'Duplicate name, %s.' % tenant['name'] - raise exception.Conflict(type='tenant', details=msg) - - self.db.set('tenant-%s' % tenant_id, tenant) - self.db.set('tenant_name-%s' % tenant['name'], tenant) - return tenant - - def update_project(self, tenant_id, tenant): - if 'name' in tenant: - tenant['name'] = clean.project_name(tenant['name']) - try: - existing = self.db.get('tenant_name-%s' % tenant['name']) - if existing and tenant_id != existing['id']: - msg = 'Duplicate name, %s.' % tenant['name'] - raise exception.Conflict(type='tenant', details=msg) - except exception.NotFound: - pass - # get the old name and delete it too - try: - old_project = self.db.get('tenant-%s' % tenant_id) - except exception.NotFound: - raise exception.ProjectNotFound(project_id=tenant_id) - new_project = old_project.copy() - new_project.update(tenant) - new_project['id'] = tenant_id - self.db.delete('tenant_name-%s' % old_project['name']) - self.db.set('tenant-%s' % tenant_id, new_project) - self.db.set('tenant_name-%s' % new_project['name'], new_project) - return new_project - - def delete_project(self, tenant_id): - try: - old_project = self.db.get('tenant-%s' % tenant_id) - except exception.NotFound: - raise exception.ProjectNotFound(project_id=tenant_id) - self.db.delete('tenant_name-%s' % old_project['name']) - self.db.delete('tenant-%s' % tenant_id) - - def create_metadata(self, user_id, tenant_id, metadata, - domain_id=None, group_id=None): - - return self.update_metadata(user_id, tenant_id, metadata, - domain_id, group_id) - - def update_metadata(self, user_id, tenant_id, metadata, - domain_id=None, group_id=None): - if user_id: - if tenant_id: - self.db.set('metadata-%s-%s' % (tenant_id, user_id), metadata) - user_ref = self._get_user(user_id) - tenants = set(user_ref.get('tenants', [])) - if tenant_id not in tenants: - tenants.add(tenant_id) - user_ref['tenants'] = list(tenants) - self.update_user(user_id, user_ref) - else: - self.db.set('metadata-%s-%s' % (domain_id, user_id), metadata) - else: - if tenant_id: - self.db.set('metadata-%s-%s' % (tenant_id, group_id), metadata) - else: - self.db.set('metadata-%s-%s' % (domain_id, group_id), metadata) - return metadata - - def create_role(self, role_id, role): - try: - self.get_role(role_id) - except exception.RoleNotFound: - pass - else: - msg = 'Duplicate ID, %s.' % role_id - raise exception.Conflict(type='role', details=msg) - - for role_ref in self.list_roles(): - if role['name'] == role_ref['name']: - msg = 'Duplicate name, %s.' % role['name'] - raise exception.Conflict(type='role', details=msg) - self.db.set('role-%s' % role_id, role) - role_list = set(self.db.get('role_list', [])) - role_list.add(role_id) - self.db.set('role_list', list(role_list)) - return role - - def update_role(self, role_id, role): - old_role_ref = None - for role_ref in self.list_roles(): - if role['name'] == role_ref['name'] and role_id != role_ref['id']: - msg = 'Duplicate name, %s.' % role['name'] - raise exception.Conflict(type='role', details=msg) - if role_id == role_ref['id']: - old_role_ref = role_ref - if old_role_ref is None: - raise exception.RoleNotFound(role_id=role_id) - new_role = old_role_ref.copy() - new_role.update(role) - new_role['id'] = role_id - self.db.set('role-%s' % role_id, new_role) - return role - - def delete_role(self, role_id): - self.get_role(role_id) - metadata_keys = filter(lambda x: x.startswith("metadata-"), - self.db.keys()) - for key in metadata_keys: - meta_id1 = key.split('-')[1] - meta_id2 = key.split('-')[2] - try: - self.delete_grant(role_id, project_id=meta_id1, - user_id=meta_id2) - except exception.NotFound: - pass - try: - self.delete_grant(role_id, project_id=meta_id1, - group_id=meta_id2) - except exception.NotFound: - pass - try: - self.delete_grant(role_id, domain_id=meta_id1, - user_id=meta_id2) - except exception.NotFound: - pass - try: - self.delete_grant(role_id, domain_id=meta_id1, - group_id=meta_id2) - except exception.NotFound: - pass - self.db.delete('role-%s' % role_id) - role_list = set(self.db.get('role_list', [])) - role_list.remove(role_id) - self.db.set('role_list', list(role_list)) - - def create_grant(self, role_id, user_id=None, group_id=None, - domain_id=None, project_id=None): - - self.get_role(role_id) - if user_id: - self.get_user(user_id) - if group_id: - self.get_group(group_id) - if domain_id: - self.get_domain(domain_id) - if project_id: - self.get_project(project_id) - - try: - metadata_ref = self.get_metadata(user_id, project_id, - domain_id, group_id) - except exception.MetadataNotFound: - metadata_ref = {} - roles = set(metadata_ref.get('roles', [])) - roles.add(role_id) - metadata_ref['roles'] = list(roles) - self.update_metadata(user_id, project_id, metadata_ref, - domain_id, group_id) - - def list_grants(self, user_id=None, group_id=None, - domain_id=None, project_id=None): - if user_id: - self.get_user(user_id) - if group_id: - self.get_group(group_id) - if domain_id: - self.get_domain(domain_id) - if project_id: - self.get_project(project_id) - - try: - metadata_ref = self.get_metadata(user_id, project_id, - domain_id, group_id) - except exception.MetadataNotFound: - metadata_ref = {} - return [self.get_role(x) for x in metadata_ref.get('roles', [])] - - def get_grant(self, role_id, user_id=None, group_id=None, - domain_id=None, project_id=None): - self.get_role(role_id) - if user_id: - self.get_user(user_id) - if group_id: - self.get_group(group_id) - if domain_id: - self.get_domain(domain_id) - if project_id: - self.get_project(project_id) - - try: - metadata_ref = self.get_metadata(user_id, project_id, - domain_id, group_id) - except exception.MetadataNotFound: - metadata_ref = {} - role_ids = set(metadata_ref.get('roles', [])) - if role_id not in role_ids: - raise exception.RoleNotFound(role_id=role_id) - return self.get_role(role_id) - - def delete_grant(self, role_id, user_id=None, group_id=None, - domain_id=None, project_id=None): - self.get_role(role_id) - if user_id: - self.get_user(user_id) - if group_id: - self.get_group(group_id) - if domain_id: - self.get_domain(domain_id) - if project_id: - self.get_project(project_id) - - try: - metadata_ref = self.get_metadata(user_id, project_id, - domain_id, group_id) - except exception.MetadataNotFound: - metadata_ref = {} - roles = set(metadata_ref.get('roles', [])) - try: - roles.remove(role_id) - except KeyError: - raise exception.RoleNotFound(role_id=role_id) - metadata_ref['roles'] = list(roles) - self.update_metadata(user_id, project_id, metadata_ref, - domain_id, group_id) - - # domain crud - - def create_domain(self, domain_id, domain): - try: - self.get_domain(domain_id) - except exception.DomainNotFound: - pass - else: - msg = 'Duplicate ID, %s.' % domain_id - raise exception.Conflict(type='domain', details=msg) - - try: - self.get_domain_by_name(domain['name']) - except exception.DomainNotFound: - pass - else: - msg = 'Duplicate name, %s.' % domain['name'] - raise exception.Conflict(type='domain', details=msg) - - self.db.set('domain-%s' % domain_id, domain) - self.db.set('domain_name-%s' % domain['name'], domain) - domain_list = set(self.db.get('domain_list', [])) - domain_list.add(domain_id) - self.db.set('domain_list', list(domain_list)) - return domain - - def list_domains(self): - domain_ids = self.db.get('domain_list', []) - return [self.get_domain(x) for x in domain_ids] - - def get_domain(self, domain_id): - try: - return self.db.get('domain-%s' % domain_id) - except exception.NotFound: - raise exception.DomainNotFound(domain_id=domain_id) - - def get_domain_by_name(self, domain_name): - try: - return self.db.get('domain_name-%s' % domain_name) - except exception.NotFound: - raise exception.DomainNotFound(domain_id=domain_name) - - def update_domain(self, domain_id, domain): - orig_domain = self.get_domain(domain_id) - domain['id'] = domain_id - self.db.set('domain-%s' % domain_id, domain) - self.db.set('domain_name-%s' % domain['name'], domain) - if domain['name'] != orig_domain['name']: - self.db.delete('domain_name-%s' % orig_domain['name']) - return domain - - def delete_domain(self, domain_id): - domain = self.get_domain(domain_id) - self.db.delete('domain-%s' % domain_id) - self.db.delete('domain_name-%s' % domain['name']) - domain_list = set(self.db.get('domain_list', [])) - domain_list.remove(domain_id) - self.db.set('domain_list', list(domain_list)) - # group crud def create_group(self, group_id, group): diff --git a/keystone/identity/backends/ldap.py b/keystone/identity/backends/ldap.py index dffbf835..91ea1e41 100644 --- a/keystone/identity/backends/ldap.py +++ b/keystone/identity/backends/ldap.py @@ -19,6 +19,7 @@ import uuid import ldap from keystone import clean +from keystone.common import dependency from keystone.common import ldap as common_ldap from keystone.common import logging from keystone.common import models @@ -38,52 +39,22 @@ DEFAULT_DOMAIN = { } +@dependency.requires('assignment_api') class Identity(identity.Driver): def __init__(self): super(Identity, self).__init__() - self.LDAP_URL = CONF.ldap.url - self.LDAP_USER = CONF.ldap.user - self.LDAP_PASSWORD = CONF.ldap.password - self.suffix = CONF.ldap.suffix - self.user = UserApi(CONF) - self.project = ProjectApi(CONF) - self.role = RoleApi(CONF) self.group = GroupApi(CONF) - def _validate_domain(self, ref): - """Validate that either the default domain or nothing is specified. - - Also removes the domain from the ref so that LDAP doesn't have to - persist the attribute. - - """ - ref = ref.copy() - domain_id = ref.pop('domain_id', CONF.identity.default_domain_id) - self._validate_domain_id(domain_id) - return ref - - def _validate_domain_id(self, domain_id): - """Validate that the domain ID specified belongs to the default domain. - - """ - if domain_id != CONF.identity.default_domain_id: - raise exception.DomainNotFound(domain_id=domain_id) - - def _set_default_domain(self, ref): - """Overrides any domain reference with the default domain.""" - if isinstance(ref, dict): - ref = ref.copy() - ref['domain_id'] = CONF.identity.default_domain_id - return ref - elif isinstance(ref, list): - return [self._set_default_domain(x) for x in ref] - else: - raise ValueError(_('Expected dict or list: %s') % type(ref)) + def default_assignment_driver(self): + return "keystone.assignment.backends.ldap.Assignment" # Identity interface - def authenticate_user(self, user_id=None, password=None): + def create_project(self, project_id, project): + return self.assignment_api.create_project(project_id, project) + + def authenticate(self, user_id, password): try: user_ref = self._get_user(user_id) except exception.UserNotFound: @@ -97,133 +68,37 @@ class Identity(identity.Driver): raise AssertionError('Invalid user / password') except Exception: raise AssertionError('Invalid user / password') - return user_ref - - def authorize_for_project(self, user_ref, tenant_id=None): - user_id = user_ref['id'] - tenant_ref = None - metadata_ref = {} - - if tenant_id is not None: - if tenant_id not in self.get_projects_for_user(user_id): - raise AssertionError('Invalid tenant') - - try: - tenant_ref = self.get_project(tenant_id) - # TODO(termie): this should probably be made into a - # get roles call - metadata_ref = self.get_metadata(user_id, tenant_id) - except exception.ProjectNotFound: - tenant_ref = None - metadata_ref = {} - except exception.MetadataNotFound: - metadata_ref = {} - - user_ref = self._set_default_domain(identity.filter_user(user_ref)) - return (user_ref, tenant_ref, metadata_ref) - - def get_project(self, tenant_id): - return self._set_default_domain(self.project.get(tenant_id)) - - def list_projects(self): - return self._set_default_domain(self.project.get_all()) - - def get_project_by_name(self, tenant_name, domain_id): - self._validate_domain_id(domain_id) - return self._set_default_domain(self.project.get_by_name(tenant_name)) + return self.assignment_api._set_default_domain( + identity.filter_user(user_ref)) def _get_user(self, user_id): return self.user.get(user_id) def get_user(self, user_id): ref = identity.filter_user(self._get_user(user_id)) - return self._set_default_domain(ref) + return self.assignment_api._set_default_domain(ref) def list_users(self): - return self._set_default_domain(self.user.get_all()) + return (self.assignment_api._set_default_domain + (self.user.get_all_filtered())) def get_user_by_name(self, user_name, domain_id): - self._validate_domain_id(domain_id) + self.assignment_api._validate_default_domain_id(domain_id) ref = identity.filter_user(self.user.get_by_name(user_name)) - return self._set_default_domain(ref) - - def get_metadata(self, user_id=None, tenant_id=None, - domain_id=None, group_id=None): - if domain_id is not None: - raise NotImplemented('Domain metadata not supported by LDAP.') - if not self.get_project(tenant_id) or not self.get_user(user_id): - return {} - - metadata_ref = self.get_roles_for_user_and_project(user_id, tenant_id) - if not metadata_ref: - return {} - return {'roles': metadata_ref} - - def get_role(self, role_id): - return self.role.get(role_id) - - def list_roles(self): - return self.role.get_all() - - def get_projects_for_user(self, user_id): - self.get_user(user_id) - user_dn = self.user._id_to_dn(user_id) - associations = (self.role.list_project_roles_for_user - (user_dn, self.project.tree_dn)) - return [p['id'] for p in - self.project.get_user_projects(user_dn, associations)] - - def get_project_users(self, tenant_id): - self.get_project(tenant_id) - tenant_dn = self.project._id_to_dn(tenant_id) - rolegrants = self.role.get_role_assignments(tenant_dn) - users = [self.user.get_filtered(self.user._dn_to_id(user_id)) - for user_id in - self.project.get_user_dns(tenant_id, rolegrants)] - return self._set_default_domain(users) - - def get_roles_for_user_and_project(self, user_id, tenant_id): - self.get_user(user_id) - self.get_project(tenant_id) - user_dn = self.user._id_to_dn(user_id) - return [self.role._dn_to_id(a.role_dn) - for a in self.role.get_role_assignments - (self.project._id_to_dn(tenant_id)) - if a.user_dn == user_dn] - - def _subrole_id_to_dn(self, role_id, tenant_id): - if tenant_id is None: - return self.role._id_to_dn(role_id) - else: - return '%s=%s,%s' % (self.role.id_attr, - ldap.dn.escape_dn_chars(role_id), - self.project._id_to_dn(tenant_id)) - - def add_role_to_user_and_project(self, user_id, tenant_id, role_id): - self.get_user(user_id) - self.get_project(tenant_id) - self.get_role(role_id) - user_dn = self.user._id_to_dn(user_id) - role_dn = self._subrole_id_to_dn(role_id, tenant_id) - self.role.add_user(role_id, role_dn, user_dn, user_id, tenant_id) - tenant_dn = self.project._id_to_dn(tenant_id) - return UserRoleAssociation( - role_dn=role_dn, - user_dn=user_dn, - tenant_dn=tenant_dn) + return self.assignment_api._set_default_domain(ref) # CRUD def create_user(self, user_id, user): - user = self._validate_domain(user) + user = self.assignment_api._validate_default_domain(user) user_ref = self.user.create(user) tenant_id = user.get('tenant_id') - user_dn = self.user._id_to_dn(user['id']) if tenant_id is not None: - self.project.add_user(tenant_id, user_dn) - return self._set_default_domain(identity.filter_user(user_ref)) + self.assignment_api.add_user_to_project(tenant_id, user_id) + return (self.assignment_api._set_default_domain + (identity.filter_user(user_ref))) def update_user(self, user_id, user): - user = self._validate_domain(user) + user = self.assignment_api._validate_default_domain(user) if 'id' in user and user['id'] != user_id: raise exception.ValidationError('Cannot change user ID') old_obj = self.user.get(user_id) @@ -246,67 +121,12 @@ class Identity(identity.Driver): user['enabled_nomask'] = old_obj['enabled_nomask'] self.user.mask_enabled_attribute(user) self.user.update(user_id, user, old_obj) - return self._set_default_domain(self.user.get_filtered(user_id)) - - def create_project(self, tenant_id, tenant): - tenant = self._validate_domain(tenant) - tenant['name'] = clean.project_name(tenant['name']) - data = tenant.copy() - if 'id' not in data or data['id'] is None: - data['id'] = str(uuid.uuid4().hex) - if 'description' in data and data['description'] in ['', None]: - data.pop('description') - return self._set_default_domain(self.project.create(data)) - - def update_project(self, tenant_id, tenant): - tenant = self._validate_domain(tenant) - if 'name' in tenant: - tenant['name'] = clean.project_name(tenant['name']) - return self._set_default_domain(self.project.update(tenant_id, tenant)) - - def create_metadata(self, user_id, tenant_id, metadata): - return {} - - def create_role(self, role_id, role): - try: - self.get_role(role_id) - except exception.NotFound: - pass - else: - msg = 'Duplicate ID, %s.' % role_id - raise exception.Conflict(type='role', details=msg) - - try: - self.role.get_by_name(role['name']) - except exception.NotFound: - pass - else: - msg = 'Duplicate name, %s.' % role['name'] - raise exception.Conflict(type='role', details=msg) - - return self.role.create(role) - - def delete_role(self, role_id): - return self.role.delete(role_id, self.project.tree_dn) - - def delete_project(self, tenant_id): - if self.project.subtree_delete_enabled: - self.project.deleteTree(id) - else: - tenant_dn = self.project._id_to_dn(tenant_id) - self.role.roles_delete_subtree_by_project(tenant_dn) - self.project.delete(tenant_id) + return (self.assignment_api._set_default_domain + (self.user.get_filtered(user_id))) def delete_user(self, user_id): + self.assignment_api.delete_user(user_id) user_dn = self.user._id_to_dn(user_id) - for ref in self.role.list_global_roles_for_user(user_dn): - self.role.delete_user(ref.role_dn, ref.user_dn, ref.project_dn, - user_id, self.role._dn_to_id(ref.role_dn)) - for ref in self.role.list_project_roles_for_user(user_dn, - self.project.tree_dn): - self.role.delete_user(ref.role_dn, ref.user_dn, ref.project_dn, - user_id, self.role._dn_to_id(ref.role_dn)) - groups = self.group.list_user_groups(user_dn) for group in groups: self.group.remove_user(user_dn, group['id'], user_id) @@ -317,30 +137,22 @@ class Identity(identity.Driver): self.user._id_to_dn(user_id)) self.user.delete(user_id) - def remove_role_from_user_and_project(self, user_id, tenant_id, role_id): - role_dn = self._subrole_id_to_dn(role_id, tenant_id) - return self.role.delete_user(role_dn, - self.user._id_to_dn(user_id), - self.project._id_to_dn(tenant_id), - user_id, role_id) - - def update_role(self, role_id, role): - self.get_role(role_id) - self.role.update(role_id, role) - def create_group(self, group_id, group): - group = self._validate_domain(group) + group = self.assignment_api._validate_default_domain(group) group['name'] = clean.group_name(group['name']) - return self._set_default_domain(self.group.create(group)) + return self.assignment_api._set_default_domain( + self.group.create(group)) def get_group(self, group_id): - return self._set_default_domain(self.group.get(group_id)) + return self.assignment_api._set_default_domain( + self.group.get(group_id)) def update_group(self, group_id, group): - group = self._validate_domain(group) + group = self.assignment_api._validate_default_domain(group) if 'name' in group: group['name'] = clean.group_name(group['name']) - return self._set_default_domain(self.group.update(group_id, group)) + return (self.assignment_api._set_default_domain + (self.group.update(group_id, group))) def delete_group(self, group_id): return self.group.delete(group_id) @@ -360,10 +172,11 @@ class Identity(identity.Driver): def list_groups_for_user(self, user_id): self.get_user(user_id) user_dn = self.user._id_to_dn(user_id) - return self._set_default_domain(self.group.list_user_groups(user_dn)) + return (self.assignment_api._set_default_domain + (self.group.list_user_groups(user_dn))) def list_groups(self): - return self._set_default_domain(self.group.get_all()) + return self.assignment_api._set_default_domain(self.group.get_all()) def list_users_in_group(self, group_id): self.get_group(group_id) @@ -371,13 +184,13 @@ class Identity(identity.Driver): for user_dn in self.group.list_group_users(group_id): user_id = self.user._dn_to_id(user_dn) try: - users.append(self.user.get(user_id)) + users.append(self.user.get_filtered(user_id)) except exception.UserNotFound: LOG.debug(_("Group member '%(user_dn)s' not found in" " '%(group_id)s'. The user should be removed" " from the group. The user will be ignored.") % dict(user_dn=user_dn, group_id=group_id)) - return self._set_default_domain(users) + return self.assignment_api._set_default_domain(users) def check_user_in_group(self, user_id, group_id): self.get_user(user_id) @@ -390,27 +203,6 @@ class Identity(identity.Driver): break return found - def create_domain(self, domain_id, domain): - if domain_id == CONF.identity.default_domain_id: - msg = 'Duplicate ID, %s.' % domain_id - raise exception.Conflict(type='domain', details=msg) - raise exception.Forbidden('Domains are read-only against LDAP') - - def get_domain(self, domain_id): - self._validate_domain_id(domain_id) - return DEFAULT_DOMAIN - - def update_domain(self, domain_id, domain): - self._validate_domain_id(domain_id) - raise exception.Forbidden('Domains are read-only against LDAP') - - def delete_domain(self, domain_id): - self._validate_domain_id(domain_id) - raise exception.Forbidden('Domains are read-only against LDAP') - - def list_domains(self): - return [DEFAULT_DOMAIN] - # TODO(termie): turn this into a data object and move logic to driver class UserApi(common_ldap.EnabledEmuMixIn, common_ldap.BaseLdap): @@ -475,292 +267,8 @@ class UserApi(common_ldap.EnabledEmuMixIn, common_ldap.BaseLdap): user = self.get(user_id) return identity.filter_user(user) - -# TODO(termie): turn this into a data object and move logic to driver -class ProjectApi(common_ldap.EnabledEmuMixIn, common_ldap.BaseLdap): - DEFAULT_OU = 'ou=Projects' - DEFAULT_STRUCTURAL_CLASSES = [] - DEFAULT_OBJECTCLASS = 'groupOfNames' - DEFAULT_ID_ATTR = 'cn' - DEFAULT_MEMBER_ATTRIBUTE = 'member' - DEFAULT_ATTRIBUTE_IGNORE = [] - NotFound = exception.ProjectNotFound - notfound_arg = 'project_id' # NOTE(yorik-sar): while options_name = tenant - options_name = 'tenant' - attribute_mapping = {'name': 'ou', - 'description': 'description', - 'tenantId': 'cn', - 'enabled': 'enabled', - 'domain_id': 'domain_id'} - model = models.Project - - def __init__(self, conf): - super(ProjectApi, self).__init__(conf) - self.attribute_mapping['name'] = conf.ldap.tenant_name_attribute - self.attribute_mapping['description'] = conf.ldap.tenant_desc_attribute - self.attribute_mapping['enabled'] = conf.ldap.tenant_enabled_attribute - self.attribute_mapping['domain_id'] = ( - conf.ldap.tenant_domain_id_attribute) - self.member_attribute = (getattr(conf.ldap, 'tenant_member_attribute') - or self.DEFAULT_MEMBER_ATTRIBUTE) - self.attribute_ignore = (getattr(conf.ldap, 'tenant_attribute_ignore') - or self.DEFAULT_ATTRIBUTE_IGNORE) - - def create(self, values): - self.affirm_unique(values) - data = values.copy() - if data.get('id') is None: - data['id'] = uuid.uuid4().hex - return super(ProjectApi, self).create(data) - - def get_user_projects(self, user_dn, associations): - """Returns list of tenants a user has access to - """ - - project_ids = set() - for assoc in associations: - project_ids.add(self._dn_to_id(assoc.project_dn)) - projects = [] - for project_id in project_ids: - #slower to get them one at a time, but a huge list could blow out - #the connection. This is the safer way - projects.append(self.get(project_id)) - return projects - - def add_user(self, tenant_id, user_dn): - conn = self.get_connection() - try: - conn.modify_s( - self._id_to_dn(tenant_id), - [(ldap.MOD_ADD, - self.member_attribute, - user_dn)]) - except ldap.TYPE_OR_VALUE_EXISTS: - # As adding a user to a tenant is done implicitly in several - # places, and is not part of the exposed API, it's easier for us to - # just ignore this instead of raising exception.Conflict. - pass - - def remove_user(self, tenant_id, user_dn, user_id): - conn = self.get_connection() - try: - conn.modify_s(self._id_to_dn(tenant_id), - [(ldap.MOD_DELETE, - self.member_attribute, - user_dn)]) - except ldap.NO_SUCH_ATTRIBUTE: - raise exception.NotFound(user_id) - - def get_user_dns(self, tenant_id, rolegrants, role_dn=None): - tenant = self._ldap_get(tenant_id) - res = set() - if not role_dn: - # Get users who have default tenant mapping - for user_dn in tenant[1].get(self.member_attribute, []): - if self.use_dumb_member and user_dn == self.dumb_member: - continue - res.add(user_dn) - - # Get users who are explicitly mapped via a tenant - for rolegrant in rolegrants: - if role_dn is None or rolegrant.role_dn == role_dn: - res.add(rolegrant.user_dn) - return list(res) - - def update(self, id, values): - old_obj = self.get(id) - if old_obj['name'] != values['name']: - msg = 'Changing Name not supported by LDAP' - raise exception.NotImplemented(message=msg) - return super(ProjectApi, self).update(id, values, old_obj) - - -class UserRoleAssociation(object): - """Role Grant model.""" - - def __init__(self, user_dn=None, role_dn=None, tenant_dn=None, - *args, **kw): - self.user_dn = user_dn - self.role_dn = role_dn - self.project_dn = tenant_dn - - -class GroupRoleAssociation(object): - """Role Grant model.""" - - def __init__(self, group_dn=None, role_dn=None, tenant_dn=None, - *args, **kw): - self.group_dn = group_dn - self.role_dn = role_dn - self.project_dn = tenant_dn - - -# TODO(termie): turn this into a data object and move logic to driver -class RoleApi(common_ldap.BaseLdap): - DEFAULT_OU = 'ou=Roles' - DEFAULT_STRUCTURAL_CLASSES = [] - DEFAULT_OBJECTCLASS = 'organizationalRole' - DEFAULT_MEMBER_ATTRIBUTE = 'roleOccupant' - DEFAULT_ATTRIBUTE_IGNORE = [] - NotFound = exception.RoleNotFound - options_name = 'role' - attribute_mapping = {'name': 'ou', - #'serviceId': 'service_id', - } - model = models.Role - - def __init__(self, conf): - super(RoleApi, self).__init__(conf) - self.attribute_mapping['name'] = conf.ldap.role_name_attribute - self.member_attribute = (getattr(conf.ldap, 'role_member_attribute') - or self.DEFAULT_MEMBER_ATTRIBUTE) - self.attribute_ignore = (getattr(conf.ldap, 'role_attribute_ignore') - or self.DEFAULT_ATTRIBUTE_IGNORE) - - def get(self, id, filter=None): - model = super(RoleApi, self).get(id, filter) - return model - - def create(self, values): - return super(RoleApi, self).create(values) - - def add_user(self, role_id, role_dn, user_dn, user_id, tenant_id=None): - conn = self.get_connection() - try: - conn.modify_s(role_dn, [(ldap.MOD_ADD, - self.member_attribute, user_dn)]) - except ldap.TYPE_OR_VALUE_EXISTS: - msg = ('User %s already has role %s in tenant %s' - % (user_id, role_id, tenant_id)) - raise exception.Conflict(type='role grant', details=msg) - except ldap.NO_SUCH_OBJECT: - if tenant_id is None or self.get(role_id) is None: - raise Exception(_("Role %s not found") % (role_id,)) - - attrs = [('objectClass', [self.object_class]), - (self.member_attribute, [user_dn])] - - if self.use_dumb_member: - attrs[1][1].append(self.dumb_member) - try: - conn.add_s(role_dn, attrs) - except Exception as inst: - raise inst - - def delete_user(self, role_dn, user_dn, tenant_dn, - user_id, role_id): - conn = self.get_connection() - try: - conn.modify_s(role_dn, [(ldap.MOD_DELETE, - self.member_attribute, user_dn)]) - except ldap.NO_SUCH_OBJECT: - if tenant_dn is None: - raise exception.RoleNotFound(role_id=role_id) - attrs = [('objectClass', [self.object_class]), - (self.member_attribute, [user_dn])] - - if self.use_dumb_member: - attrs[1][1].append(self.dumb_member) - try: - conn.add_s(role_dn, attrs) - except Exception as inst: - raise inst - except ldap.NO_SUCH_ATTRIBUTE: - raise exception.UserNotFound(user_id=user_id) - - def get_role_assignments(self, tenant_dn): - conn = self.get_connection() - query = '(objectClass=%s)' % self.object_class - - try: - roles = conn.search_s(tenant_dn, ldap.SCOPE_ONELEVEL, query) - except ldap.NO_SUCH_OBJECT: - return [] - - res = [] - for role_dn, attrs in roles: - try: - user_dns = attrs[self.member_attribute] - except KeyError: - continue - for user_dn in user_dns: - if self.use_dumb_member and user_dn == self.dumb_member: - continue - res.append(UserRoleAssociation( - user_dn=user_dn, - role_dn=role_dn, - tenant_dn=tenant_dn)) - - return res - - def list_global_roles_for_user(self, user_dn): - roles = self.get_all('(%s=%s)' % (self.member_attribute, user_dn)) - return [UserRoleAssociation( - role_dn=role.dn, - user_dn=user_dn) for role in roles] - - def list_project_roles_for_user(self, user_dn, project_subtree): - conn = self.get_connection() - query = '(&(objectClass=%s)(%s=%s))' % (self.object_class, - self.member_attribute, - user_dn) - try: - roles = conn.search_s(project_subtree, - ldap.SCOPE_SUBTREE, - query) - except ldap.NO_SUCH_OBJECT: - return [] - - res = [] - for role_dn, _ in roles: - #ldap.dn.dn2str returns an array, where the first - #element is the first segment. - #For a role assignment, this contains the role ID, - #The remainder is the DN of the tenant. - tenant = ldap.dn.str2dn(role_dn) - tenant.pop(0) - tenant_dn = ldap.dn.dn2str(tenant) - res.append(UserRoleAssociation( - user_dn=user_dn, - role_dn=role_dn, - tenant_dn=tenant_dn)) - return res - - def roles_delete_subtree_by_project(self, tenant_dn): - conn = self.get_connection() - query = '(objectClass=%s)' % self.object_class - try: - roles = conn.search_s(tenant_dn, ldap.SCOPE_ONELEVEL, query) - for role_dn, _ in roles: - try: - conn.delete_s(role_dn) - except Exception as inst: - raise inst - except ldap.NO_SUCH_OBJECT: - pass - - def update(self, role_id, role): - if role['id'] != role_id: - raise exception.ValidationError('Cannot change role ID') - try: - old_name = self.get_by_name(role['name']) - raise exception.Conflict('Cannot duplicate name %s' % old_name) - except exception.NotFound: - pass - return super(RoleApi, self).update(role_id, role) - - def delete(self, id, tenant_dn): - conn = self.get_connection() - query = '(&(objectClass=%s)(%s=%s))' % (self.object_class, - self.id_attr, id) - try: - for role_dn, _ in conn.search_s(tenant_dn, - ldap.SCOPE_SUBTREE, - query): - conn.delete_s(role_dn) - except ldap.NO_SUCH_OBJECT: - pass - super(RoleApi, self).delete(id) + def get_all_filtered(self): + return [identity.filter_user(user) for user in self.get_all()] class GroupApi(common_ldap.BaseLdap): diff --git a/keystone/identity/backends/pam.py b/keystone/identity/backends/pam.py index 9c4bbf38..2a6ee621 100644 --- a/keystone/identity/backends/pam.py +++ b/keystone/identity/backends/pam.py @@ -58,21 +58,13 @@ class PamIdentity(identity.Driver): Tenant is always the same as User, root user has admin role. """ - def authenticate_user(self, user_id=None, password=None): + def authenticate(self, user_id, password): auth = pam.authenticate if pam else PAM_authenticate if not auth(user_id, password): raise AssertionError('Invalid user / password') user = {'id': user_id, 'name': user_id} return user - def authorize_for_project(self, user_ref, tenant_id=None): - user_id = user_ref['id'] - metadata = {} - if user_id == 'root': - metadata['is_admin'] = True - tenant = {'id': user_id, 'name': user_id} - return (user_ref, tenant, metadata) - def get_project(self, tenant_id): return {'id': tenant_id, 'name': tenant_id} @@ -134,16 +126,16 @@ class PamIdentity(identity.Driver): def delete_project(self, tenant_id, tenant): raise NotImplementedError() - def get_metadata(self, user_id, tenant_id): + def _get_metadata(self, user_id, tenant_id): metadata = {} if user_id == 'root': metadata['is_admin'] = True return metadata - def create_metadata(self, user_id, tenant_id, metadata): + def _create_metadata(self, user_id, tenant_id, metadata): raise NotImplementedError() - def update_metadata(self, user_id, tenant_id, metadata): + def _update_metadata(self, user_id, tenant_id, metadata): raise NotImplementedError() def create_role(self, role_id, role): diff --git a/keystone/identity/backends/sql.py b/keystone/identity/backends/sql.py index f81feb1d..bff41106 100644 --- a/keystone/identity/backends/sql.py +++ b/keystone/identity/backends/sql.py @@ -14,7 +14,7 @@ # License for the specific language governing permissions and limitations # under the License. -from keystone import clean +from keystone.common import dependency from keystone.common import sql from keystone.common.sql import migration from keystone.common import utils @@ -51,78 +51,6 @@ class Group(sql.ModelBase, sql.DictBase): __table_args__ = (sql.UniqueConstraint('domain_id', 'name'), {}) -class Domain(sql.ModelBase, sql.DictBase): - __tablename__ = 'domain' - attributes = ['id', 'name', 'enabled'] - id = sql.Column(sql.String(64), primary_key=True) - name = sql.Column(sql.String(64), unique=True, nullable=False) - enabled = sql.Column(sql.Boolean, default=True) - extra = sql.Column(sql.JsonBlob()) - - -class Project(sql.ModelBase, sql.DictBase): - __tablename__ = 'project' - attributes = ['id', 'name', 'domain_id', 'description', 'enabled'] - id = sql.Column(sql.String(64), primary_key=True) - name = sql.Column(sql.String(64), nullable=False) - domain_id = sql.Column(sql.String(64), sql.ForeignKey('domain.id'), - nullable=False) - description = sql.Column(sql.Text()) - enabled = sql.Column(sql.Boolean) - extra = sql.Column(sql.JsonBlob()) - # Unique constraint across two columns to create the separation - # rather than just only 'name' being unique - __table_args__ = (sql.UniqueConstraint('domain_id', 'name'), {}) - - -class Role(sql.ModelBase, sql.DictBase): - __tablename__ = 'role' - attributes = ['id', 'name'] - id = sql.Column(sql.String(64), primary_key=True) - name = sql.Column(sql.String(64), unique=True, nullable=False) - extra = sql.Column(sql.JsonBlob()) - - -class BaseGrant(sql.DictBase): - def to_dict(self): - """Override parent to_dict() method with a simpler implementation. - - Grant tables don't have non-indexed 'extra' attributes, so the - parent implementation is not applicable. - """ - return dict(self.iteritems()) - - -class UserProjectGrant(sql.ModelBase, BaseGrant): - __tablename__ = 'user_project_metadata' - user_id = sql.Column(sql.String(64), - primary_key=True) - project_id = sql.Column(sql.String(64), - primary_key=True) - data = sql.Column(sql.JsonBlob()) - - -class UserDomainGrant(sql.ModelBase, BaseGrant): - __tablename__ = 'user_domain_metadata' - user_id = sql.Column(sql.String(64), primary_key=True) - domain_id = sql.Column(sql.String(64), primary_key=True) - data = sql.Column(sql.JsonBlob()) - - -class GroupProjectGrant(sql.ModelBase, BaseGrant): - __tablename__ = 'group_project_metadata' - group_id = sql.Column(sql.String(64), primary_key=True) - project_id = sql.Column(sql.String(64), primary_key=True) - data = sql.Column(sql.JsonBlob()) - - -class GroupDomainGrant(sql.ModelBase, BaseGrant): - __tablename__ = 'group_domain_metadata' - group_id = sql.Column(sql.String(64), primary_key=True) - domain_id = sql.Column(sql.String(64), primary_key=True) - data = sql.Column(sql.JsonBlob()) - - class UserGroupMembership(sql.ModelBase, sql.DictBase): """Group membership join table.""" __tablename__ = 'user_group_membership' @@ -134,7 +62,11 @@ class UserGroupMembership(sql.ModelBase, sql.DictBase): primary_key=True) +@dependency.requires('assignment_api') class Identity(sql.Base, identity.Driver): + def default_assignment_driver(self): + return "keystone.assignment.backends.sql.Assignment" + # Internal interface to manage the database def db_sync(self, version=None): migration.db_sync(version=version) @@ -154,7 +86,7 @@ class Identity(sql.Base, identity.Driver): return utils.check_password(password, user_ref.password) # Identity interface - def authenticate_user(self, user_id=None, password=None): + def authenticate(self, user_id, password): session = self.get_session() user_ref = None try: @@ -163,464 +95,7 @@ class Identity(sql.Base, identity.Driver): raise AssertionError('Invalid user / password') if not self._check_password(password, user_ref): raise AssertionError('Invalid user / password') - return user_ref - - def authorize_for_project(self, user_ref, tenant_id=None): - user_id = user_ref['id'] - tenant_ref = None - metadata_ref = {} - if tenant_id is not None: - # FIXME(gyee): this should really be - # get_roles_for_user_and_project() after the dusts settle - if tenant_id not in self.get_projects_for_user(user_id): - raise AssertionError('Invalid project') - try: - tenant_ref = self.get_project(tenant_id) - metadata_ref = self.get_metadata(user_id, tenant_id) - except exception.ProjectNotFound: - tenant_ref = None - metadata_ref = {} - except exception.MetadataNotFound: - metadata_ref = {} - user_ref = identity.filter_user(user_ref.to_dict()) - return (user_ref, tenant_ref, metadata_ref) - - def _get_project(self, session, project_id): - project_ref = session.query(Project).get(project_id) - if project_ref is None: - raise exception.ProjectNotFound(project_id=project_id) - return project_ref - - def get_project(self, tenant_id): - session = self.get_session() - return self._get_project(session, tenant_id).to_dict() - - def get_project_by_name(self, tenant_name, domain_id): - session = self.get_session() - query = session.query(Project) - query = query.filter_by(name=tenant_name) - query = query.filter_by(domain_id=domain_id) - try: - project_ref = query.one() - except sql.NotFound: - raise exception.ProjectNotFound(project_id=tenant_name) - return project_ref.to_dict() - - def get_project_user_ids(self, tenant_id): - session = self.get_session() - self.get_project(tenant_id) - query = session.query(UserProjectGrant) - query = query.filter(UserProjectGrant.project_id == tenant_id) - project_refs = query.all() - return [project_ref.user_id for project_ref in project_refs] - - def get_project_users(self, tenant_id): - session = self.get_session() - self.get_project(tenant_id) - user_refs = [] - for user_id in self.get_project_user_ids(tenant_id): - query = session.query(User) - query = query.filter(User.id == user_id) - user_ref = query.first() - user_refs.append(identity.filter_user(user_ref.to_dict())) - return user_refs - - def get_metadata(self, user_id=None, tenant_id=None, - domain_id=None, group_id=None): - session = self.get_session() - - if user_id: - if tenant_id: - q = session.query(UserProjectGrant) - q = q.filter_by(project_id=tenant_id) - elif domain_id: - q = session.query(UserDomainGrant) - q = q.filter_by(domain_id=domain_id) - q = q.filter_by(user_id=user_id) - elif group_id: - if tenant_id: - q = session.query(GroupProjectGrant) - q = q.filter_by(project_id=tenant_id) - elif domain_id: - q = session.query(GroupDomainGrant) - q = q.filter_by(domain_id=domain_id) - q = q.filter_by(group_id=group_id) - try: - return q.one().data - except sql.NotFound: - raise exception.MetadataNotFound() - - def create_grant(self, role_id, user_id=None, group_id=None, - domain_id=None, project_id=None): - session = self.get_session() - self._get_role(session, role_id) - if user_id: - self._get_user(session, user_id) - if group_id: - self._get_group(session, group_id) - if domain_id: - self._get_domain(session, domain_id) - if project_id: - self._get_project(session, project_id) - - try: - metadata_ref = self.get_metadata(user_id, project_id, - domain_id, group_id) - is_new = False - except exception.MetadataNotFound: - metadata_ref = {} - is_new = True - roles = set(metadata_ref.get('roles', [])) - roles.add(role_id) - metadata_ref['roles'] = list(roles) - if is_new: - self.create_metadata(user_id, project_id, metadata_ref, - domain_id, group_id) - else: - self.update_metadata(user_id, project_id, metadata_ref, - domain_id, group_id) - - def list_grants(self, user_id=None, group_id=None, - domain_id=None, project_id=None): - session = self.get_session() - if user_id: - self._get_user(session, user_id) - if group_id: - self._get_group(session, group_id) - if domain_id: - self._get_domain(session, domain_id) - if project_id: - self._get_project(session, project_id) - - try: - metadata_ref = self.get_metadata(user_id, project_id, - domain_id, group_id) - except exception.MetadataNotFound: - metadata_ref = {} - return [self.get_role(x) for x in metadata_ref.get('roles', [])] - - def get_grant(self, role_id, user_id=None, group_id=None, - domain_id=None, project_id=None): - session = self.get_session() - role_ref = self._get_role(session, role_id) - if user_id: - self._get_user(session, user_id) - if group_id: - self._get_group(session, group_id) - if domain_id: - self._get_domain(session, domain_id) - if project_id: - self._get_project(session, project_id) - - try: - metadata_ref = self.get_metadata(user_id, project_id, - domain_id, group_id) - except exception.MetadataNotFound: - metadata_ref = {} - role_ids = set(metadata_ref.get('roles', [])) - if role_id not in role_ids: - raise exception.RoleNotFound(role_id=role_id) - return role_ref.to_dict() - - def delete_grant(self, role_id, user_id=None, group_id=None, - domain_id=None, project_id=None): - session = self.get_session() - self._get_role(session, role_id) - if user_id: - self._get_user(session, user_id) - if group_id: - self._get_group(session, group_id) - if domain_id: - self._get_domain(session, domain_id) - if project_id: - self._get_project(session, project_id) - - try: - metadata_ref = self.get_metadata(user_id, project_id, - domain_id, group_id) - is_new = False - except exception.MetadataNotFound: - metadata_ref = {} - is_new = True - roles = set(metadata_ref.get('roles', [])) - try: - roles.remove(role_id) - except KeyError: - raise exception.RoleNotFound(role_id=role_id) - metadata_ref['roles'] = list(roles) - if is_new: - self.create_metadata(user_id, project_id, metadata_ref, - domain_id, group_id) - else: - self.update_metadata(user_id, project_id, metadata_ref, - domain_id, group_id) - - def list_projects(self): - session = self.get_session() - tenant_refs = session.query(Project).all() - return [tenant_ref.to_dict() for tenant_ref in tenant_refs] - - def get_projects_for_user(self, user_id): - session = self.get_session() - self._get_user(session, user_id) - query = session.query(UserProjectGrant) - query = query.filter_by(user_id=user_id) - membership_refs = query.all() - return [x.project_id for x in membership_refs] - - def _get_user_group_project_roles(self, metadata_ref, user_id, project_id): - group_refs = self.list_groups_for_user(user_id=user_id) - for x in group_refs: - try: - metadata_ref.update( - self.get_metadata(group_id=x['id'], - tenant_id=project_id)) - except exception.MetadataNotFound: - # no group grant, skip - pass - - def _get_user_project_roles(self, metadata_ref, user_id, project_id): - try: - metadata_ref.update(self.get_metadata(user_id, project_id)) - except exception.MetadataNotFound: - pass - - def get_roles_for_user_and_project(self, user_id, tenant_id): - session = self.get_session() - self._get_user(session, user_id) - self._get_project(session, tenant_id) - metadata_ref = {} - self._get_user_project_roles(metadata_ref, user_id, tenant_id) - self._get_user_group_project_roles(metadata_ref, user_id, tenant_id) - return list(set(metadata_ref.get('roles', []))) - - def add_role_to_user_and_project(self, user_id, tenant_id, role_id): - session = self.get_session() - self._get_user(session, user_id) - self._get_project(session, tenant_id) - self._get_role(session, role_id) - try: - metadata_ref = self.get_metadata(user_id, tenant_id) - is_new = False - except exception.MetadataNotFound: - metadata_ref = {} - is_new = True - roles = set(metadata_ref.get('roles', [])) - if role_id in roles: - msg = ('User %s already has role %s in tenant %s' - % (user_id, role_id, tenant_id)) - raise exception.Conflict(type='role grant', details=msg) - roles.add(role_id) - metadata_ref['roles'] = list(roles) - if is_new: - self.create_metadata(user_id, tenant_id, metadata_ref) - else: - self.update_metadata(user_id, tenant_id, metadata_ref) - - def remove_role_from_user_and_project(self, user_id, tenant_id, role_id): - try: - metadata_ref = self.get_metadata(user_id, tenant_id) - roles = set(metadata_ref.get('roles', [])) - if role_id not in roles: - raise exception.RoleNotFound(message=_( - 'Cannot remove role that has not been granted, %s') % - role_id) - roles.remove(role_id) - metadata_ref['roles'] = list(roles) - if len(roles): - self.update_metadata(user_id, tenant_id, metadata_ref) - else: - session = self.get_session() - q = session.query(UserProjectGrant) - q = q.filter_by(user_id=user_id) - q = q.filter_by(project_id=tenant_id) - q.delete() - except exception.MetadataNotFound: - msg = 'Cannot remove role that has not been granted, %s' % role_id - raise exception.RoleNotFound(message=msg) - - # CRUD - @sql.handle_conflicts(type='project') - def create_project(self, tenant_id, tenant): - tenant['name'] = clean.project_name(tenant['name']) - session = self.get_session() - with session.begin(): - tenant_ref = Project.from_dict(tenant) - session.add(tenant_ref) - session.flush() - return tenant_ref.to_dict() - - @sql.handle_conflicts(type='project') - def update_project(self, tenant_id, tenant): - session = self.get_session() - - if 'name' in tenant: - tenant['name'] = clean.project_name(tenant['name']) - - with session.begin(): - tenant_ref = self._get_project(session, tenant_id) - old_project_dict = tenant_ref.to_dict() - for k in tenant: - old_project_dict[k] = tenant[k] - new_project = Project.from_dict(old_project_dict) - for attr in Project.attributes: - if attr != 'id': - setattr(tenant_ref, attr, getattr(new_project, attr)) - tenant_ref.extra = new_project.extra - session.flush() - return tenant_ref.to_dict(include_extra_dict=True) - - @sql.handle_conflicts(type='project') - def delete_project(self, tenant_id): - session = self.get_session() - - with session.begin(): - tenant_ref = self._get_project(session, tenant_id) - - q = session.query(UserProjectGrant) - q = q.filter_by(project_id=tenant_id) - q.delete(False) - - q = session.query(UserProjectGrant) - q = q.filter_by(project_id=tenant_id) - q.delete(False) - - q = session.query(GroupProjectGrant) - q = q.filter_by(project_id=tenant_id) - q.delete(False) - - session.delete(tenant_ref) - session.flush() - - @sql.handle_conflicts(type='metadata') - def create_metadata(self, user_id, tenant_id, metadata, - domain_id=None, group_id=None): - session = self.get_session() - with session.begin(): - if user_id: - if tenant_id: - session.add(UserProjectGrant(user_id=user_id, - project_id=tenant_id, - data=metadata)) - elif domain_id: - session.add(UserDomainGrant(user_id=user_id, - domain_id=domain_id, - data=metadata)) - elif group_id: - if tenant_id: - session.add(GroupProjectGrant(group_id=group_id, - project_id=tenant_id, - data=metadata)) - elif domain_id: - session.add(GroupDomainGrant(group_id=group_id, - domain_id=domain_id, - data=metadata)) - session.flush() - return metadata - - @sql.handle_conflicts(type='metadata') - def update_metadata(self, user_id, tenant_id, metadata, - domain_id=None, group_id=None): - session = self.get_session() - with session.begin(): - if user_id: - if tenant_id: - q = session.query(UserProjectGrant) - q = q.filter_by(user_id=user_id) - q = q.filter_by(project_id=tenant_id) - elif domain_id: - q = session.query(UserDomainGrant) - q = q.filter_by(user_id=user_id) - q = q.filter_by(domain_id=domain_id) - elif group_id: - if tenant_id: - q = session.query(GroupProjectGrant) - q = q.filter_by(group_id=group_id) - q = q.filter_by(project_id=tenant_id) - elif domain_id: - q = session.query(GroupDomainGrant) - q = q.filter_by(group_id=group_id) - q = q.filter_by(domain_id=domain_id) - metadata_ref = q.first() - data = metadata_ref.data.copy() - data.update(metadata) - metadata_ref.data = data - session.flush() - return metadata_ref - - # domain crud - - @sql.handle_conflicts(type='domain') - def create_domain(self, domain_id, domain): - session = self.get_session() - with session.begin(): - ref = Domain.from_dict(domain) - session.add(ref) - session.flush() - return ref.to_dict() - - def list_domains(self): - session = self.get_session() - refs = session.query(Domain).all() - return [ref.to_dict() for ref in refs] - - def _get_domain(self, session, domain_id): - ref = session.query(Domain).get(domain_id) - if ref is None: - raise exception.DomainNotFound(domain_id=domain_id) - return ref - - def get_domain(self, domain_id): - session = self.get_session() - return self._get_domain(session, domain_id).to_dict() - - def get_domain_by_name(self, domain_name): - session = self.get_session() - try: - ref = session.query(Domain).filter_by(name=domain_name).one() - except sql.NotFound: - raise exception.DomainNotFound(domain_id=domain_name) - return ref.to_dict() - - @sql.handle_conflicts(type='domain') - def update_domain(self, domain_id, domain): - session = self.get_session() - with session.begin(): - ref = self._get_domain(session, domain_id) - old_dict = ref.to_dict() - for k in domain: - old_dict[k] = domain[k] - new_domain = Domain.from_dict(old_dict) - for attr in Domain.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_domain, attr)) - ref.extra = new_domain.extra - session.flush() - return ref.to_dict() - - def delete_domain(self, domain_id): - session = self.get_session() - with session.begin(): - ref = self._get_domain(session, domain_id) - session.delete(ref) - session.flush() - - def list_user_projects(self, user_id): - session = self.get_session() - user = self.get_user(user_id) - metadata_refs = session\ - .query(UserProjectGrant)\ - .filter_by(user_id=user_id) - project_ids = set([x.project_id for x in metadata_refs - if x.data.get('roles')]) - if user.get('project_id'): - project_ids.add(user['project_id']) - - # FIXME(dolph): this should be removed with proper migrations - if user.get('tenant_id'): - project_ids.add(user['tenant_id']) - - return [self.get_project(x) for x in project_ids] + return identity.filter_user(user_ref.to_dict()) # user crud @@ -742,20 +217,13 @@ class Identity(sql.Base, identity.Driver): with session.begin(): ref = self._get_user(session, user_id) - q = session.query(UserProjectGrant) - q = q.filter_by(user_id=user_id) - q.delete(False) - - q = session.query(UserDomainGrant) - q = q.filter_by(user_id=user_id) - q.delete(False) - q = session.query(UserGroupMembership) q = q.filter_by(user_id=user_id) q.delete(False) session.delete(ref) session.flush() + self.assignment_api.delete_user(user_id) # group crud @@ -806,92 +274,10 @@ class Identity(sql.Base, identity.Driver): with session.begin(): ref = self._get_group(session, group_id) - q = session.query(GroupProjectGrant) - q = q.filter_by(group_id=group_id) - q.delete(False) - - q = session.query(GroupDomainGrant) - q = q.filter_by(group_id=group_id) - q.delete(False) - q = session.query(UserGroupMembership) q = q.filter_by(group_id=group_id) q.delete(False) session.delete(ref) session.flush() - - # role crud - - @sql.handle_conflicts(type='role') - def create_role(self, role_id, role): - session = self.get_session() - with session.begin(): - ref = Role.from_dict(role) - session.add(ref) - session.flush() - return ref.to_dict() - - def list_roles(self): - session = self.get_session() - refs = session.query(Role).all() - return [ref.to_dict() for ref in refs] - - def _get_role(self, session, role_id): - ref = session.query(Role).get(role_id) - if ref is None: - raise exception.RoleNotFound(role_id=role_id) - return ref - - def get_role(self, role_id): - session = self.get_session() - return self._get_role(session, role_id).to_dict() - - @sql.handle_conflicts(type='role') - def update_role(self, role_id, role): - session = self.get_session() - with session.begin(): - ref = self._get_role(session, role_id) - old_dict = ref.to_dict() - for k in role: - old_dict[k] = role[k] - new_role = Role.from_dict(old_dict) - for attr in Role.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_role, attr)) - ref.extra = new_role.extra - session.flush() - return ref.to_dict() - - def delete_role(self, role_id): - session = self.get_session() - - with session.begin(): - ref = self._get_role(session, role_id) - for metadata_ref in session.query(UserProjectGrant): - try: - self.delete_grant(role_id, user_id=metadata_ref.user_id, - project_id=metadata_ref.project_id) - except exception.RoleNotFound: - pass - for metadata_ref in session.query(UserDomainGrant): - try: - self.delete_grant(role_id, user_id=metadata_ref.user_id, - domain_id=metadata_ref.domain_id) - except exception.RoleNotFound: - pass - for metadata_ref in session.query(GroupProjectGrant): - try: - self.delete_grant(role_id, group_id=metadata_ref.group_id, - project_id=metadata_ref.project_id) - except exception.RoleNotFound: - pass - for metadata_ref in session.query(GroupDomainGrant): - try: - self.delete_grant(role_id, group_id=metadata_ref.group_id, - domain_id=metadata_ref.domain_id) - except exception.RoleNotFound: - pass - - session.delete(ref) - session.flush() + self.assignment_api.delete_group(group_id) diff --git a/keystone/identity/controllers.py b/keystone/identity/controllers.py index f798e3dc..7ca1f8bf 100644 --- a/keystone/identity/controllers.py +++ b/keystone/identity/controllers.py @@ -16,6 +16,7 @@ """Workflow Logic the Identity service.""" +import copy import urllib import urlparse import uuid @@ -402,6 +403,8 @@ class DomainV3(controller.V3Controller): @controller.protected def create_domain(self, context, domain): + self._require_attribute(domain, 'name') + ref = self._assign_unique_id(self._normalize_dict(domain)) ref = self.identity_api.create_domain(ref['id'], ref) return DomainV3.wrap_member(context, ref) @@ -543,6 +546,8 @@ class ProjectV3(controller.V3Controller): @controller.protected def create_project(self, context, project): + self._require_attribute(project, 'name') + ref = self._assign_unique_id(self._normalize_dict(project)) ref = self._normalize_domain_id(context, ref) ref = self.identity_api.create_project(ref['id'], ref) @@ -591,6 +596,8 @@ class UserV3(controller.V3Controller): @controller.protected def create_user(self, context, user): + self._require_attribute(user, 'name') + ref = self._assign_unique_id(self._normalize_dict(user)) ref = self._normalize_domain_id(context, ref) ref = self.identity_api.create_user(ref['id'], ref) @@ -662,6 +669,8 @@ class GroupV3(controller.V3Controller): @controller.protected def create_group(self, context, group): + self._require_attribute(group, 'name') + ref = self._assign_unique_id(self._normalize_dict(group)) ref = self._normalize_domain_id(context, ref) ref = self.identity_api.create_group(ref['id'], ref) @@ -712,6 +721,8 @@ class RoleV3(controller.V3Controller): @controller.protected def create_role(self, context, role): + self._require_attribute(role, 'name') + ref = self._assign_unique_id(self._normalize_dict(role)) ref = self.identity_api.create_role(ref['id'], ref) return RoleV3.wrap_member(context, ref) @@ -747,6 +758,11 @@ class RoleV3(controller.V3Controller): msg = 'Specify a user or group, not both' raise exception.ValidationError(msg) + def _check_if_inherited(self, context): + return (CONF.os_inherit.enabled and + context['path'].startswith('/OS-INHERIT') and + context['path'].endswith('/inherited_to_projects')) + @controller.protected def create_grant(self, context, role_id, user_id=None, group_id=None, domain_id=None, project_id=None): @@ -755,7 +771,8 @@ class RoleV3(controller.V3Controller): self._require_user_xor_group(user_id, group_id) self.identity_api.create_grant( - role_id, user_id, group_id, domain_id, project_id) + role_id, user_id, group_id, domain_id, project_id, + self._check_if_inherited(context)) @controller.protected def list_grants(self, context, user_id=None, group_id=None, @@ -765,7 +782,8 @@ class RoleV3(controller.V3Controller): self._require_user_xor_group(user_id, group_id) refs = self.identity_api.list_grants( - user_id, group_id, domain_id, project_id) + user_id, group_id, domain_id, project_id, + self._check_if_inherited(context)) return RoleV3.wrap_collection(context, refs) @controller.protected @@ -776,7 +794,8 @@ class RoleV3(controller.V3Controller): self._require_user_xor_group(user_id, group_id) self.identity_api.get_grant( - role_id, user_id, group_id, domain_id, project_id) + role_id, user_id, group_id, domain_id, project_id, + self._check_if_inherited(context)) @controller.protected def revoke_grant(self, context, role_id, user_id=None, group_id=None, @@ -786,7 +805,8 @@ class RoleV3(controller.V3Controller): self._require_user_xor_group(user_id, group_id) self.identity_api.delete_grant( - role_id, user_id, group_id, domain_id, project_id) + role_id, user_id, group_id, domain_id, project_id, + self._check_if_inherited(context)) # Now delete any tokens for this user or, in the case of a group, # tokens from all the uses who are members of this group. @@ -794,3 +814,330 @@ class RoleV3(controller.V3Controller): self._delete_tokens_for_user(user_id) else: self._delete_tokens_for_group(group_id) + + +class RoleAssignmentV3(controller.V3Controller): + + # TODO(henry-nash): The current implementation does not provide a full + # first class entity for role-assignment. There is no role_assignment_id + # and only the list_role_assignment call is supported. Further, since it + # is not a first class entity, the links for the individual entities + # reference the individual role grant APIs. + + collection_name = 'role_assignments' + member_name = 'role_assignment' + + @classmethod + def wrap_member(cls, context, ref): + # NOTE(henry-nash): Since we are not yet a true collection, we override + # the wrapper as have already included the links in the entities + pass + + def _format_entity(self, entity): + """Format an assignment entity for API response. + + The driver layer returns entities as dicts containing the ids of the + actor (e.g. user or group), target (e.g. domain or project) and role. + If it is an inherited role, then this is also indicated. Examples: + + {'user_id': user_id, + 'project_id': domain_id, + 'role_id': role_id} + + or, for an inherited role: + + {'user_id': user_id, + 'domain_id': domain_id, + 'role_id': role_id, + 'inherited_to_projects': true} + + This function maps this into the format to be returned via the API, + e.g. for the second example above: + + { + 'user': { + {'id': user_id} + }, + 'scope': { + 'domain': { + {'id': domain_id} + }, + 'OS-INHERIT:inherited_to': 'projects + }, + 'role': { + {'id': role_id} + }, + 'links': { + 'assignment': '/domains/domain_id/users/user_id/roles/' + 'role_id/inherited_to_projects' + } + } + + """ + + formatted_entity = {} + suffix = "" + if 'user_id' in entity: + formatted_entity['user'] = {'id': entity['user_id']} + actor_link = 'users/%s' % entity['user_id'] + if 'group_id' in entity: + formatted_entity['group'] = {'id': entity['group_id']} + actor_link = 'groups/%s' % entity['group_id'] + if 'role_id' in entity: + formatted_entity['role'] = {'id': entity['role_id']} + if 'project_id' in entity: + formatted_entity['scope'] = ( + {'project': {'id': entity['project_id']}}) + target_link = '/projects/%s' % entity['project_id'] + if 'domain_id' in entity: + formatted_entity['scope'] = ( + {'domain': {'id': entity['domain_id']}}) + if 'inherited_to_projects' in entity: + formatted_entity['scope']['OS-INHERIT:inherited_to'] = ( + 'projects') + target_link = '/OS-INHERIT/domains/%s' % entity['domain_id'] + suffix = '/inherited_to_projects' + else: + target_link = '/domains/%s' % entity['domain_id'] + formatted_entity.setdefault('links', {}) + formatted_entity['links']['assignment'] = ( + self.base_url('%(target)s/%(actor)s/roles/%(role)s%(suffix)s' % { + 'target': target_link, + 'actor': actor_link, + 'role': entity['role_id'], + 'suffix': suffix})) + + return formatted_entity + + def _expand_indirect_assignments(self, refs): + """Processes entity list into all-direct assignments. + + For any group role assignments in the list, create a role assignment + entity for each member of that group, and then remove the group + assignment entity itself from the list. + + If the OS-INHERIT extension is enabled, then honor any inherited + roles on the domain by creating the equivalent on all projects + owned by the domain. + + For any new entity created by virtue of group membership, add in an + additional link to that membership. + + """ + def _get_group_members(ref): + """Get a list of group members. + + Get the list of group members. If this fails with + GroupNotFound, then log this as a warning, but allow + overall processing to continue. + + """ + try: + members = self.identity_api.list_users_in_group( + ref['group']['id']) + except exception.GroupNotFound: + members = [] + # The group is missing, which should not happen since + # group deletion should remove any related assignments, so + # log a warning + if 'domain' in ref: + target = 'Domain: %s' % ref['domain'].get('domain_id') + elif 'project' in ref: + target = 'Project: %s' % ref['project'].get('project_id') + else: + # Should always be a domain or project, but since to get + # here things have gone astray, let's be cautious. + target = 'Unknown' + LOG.warning( + _('Group %(group)s not found for role-assignment - ' + '%(target)s with Role: %(role)s') % { + 'group': ref['group_id'], 'target': target, + 'role': ref.get('role_id')}) + return members + + def _build_user_assignment_equivalent_of_group( + user, group_id, template): + """Create a user assignment equivalent to the group one. + + The template has had the 'group' entity removed, so + substitute a 'user' one. The 'assignment' link stays as it is, + referring to the group assignment that led to this role. + A 'membership' link is added that refers to this particular + user's membership of this group. + + """ + user_entry = copy.deepcopy(template) + user_entry['user'] = {'id': user['id']} + user_entry['links']['membership'] = ( + self.base_url('/groups/%s/users/%s' % + (group_id, user['id']))) + return user_entry + + def _build_project_equivalent_of_user_domain_role( + project_id, domain_id, template): + """Create a user project assignment equivalent to the domain one. + + The template has had the 'domain' entity removed, so + substitute a 'project' one, modifying the 'assignment' link + to match. + + """ + project_entry = copy.deepcopy(template) + project_entry['scope']['project'] = {'id': project_id} + project_entry['links']['assignment'] = ( + self.base_url( + '/OS-INHERIT/domains/%s/users/%s/roles/%s' + '/inherited_to_projects' % ( + domain_id, project_entry['user']['id'], + project_entry['role']['id']))) + return project_entry + + def _build_project_equivalent_of_group_domain_role( + user_id, group_id, project_id, domain_id, template): + """Create a user project equivalent to the domain group one. + + The template has had the 'domain' and 'group' entities removed, so + substitute a 'user-project' one, modifying the 'assignment' link + to match. + + """ + project_entry = copy.deepcopy(template) + project_entry['user'] = {'id': user_id} + project_entry['scope']['project'] = {'id': project_id} + project_entry['links']['assignment'] = ( + self.base_url('/OS-INHERIT/domains/%s/groups/%s/roles/%s' + '/inherited_to_projects' % ( + domain_id, group_id, + project_entry['role']['id']))) + project_entry['links']['membership'] = ( + self.base_url('/groups/%s/users/%s' % + (group_id, user_id))) + return project_entry + + # Scan the list of entities for any assignments that need to be + # expanded. + # + # If the OS-INERIT extension is enabled, the refs lists may + # contain roles to be inherited from domain to project, so expand + # these as well into project equivalents + # + # For any regular group entries, expand these into user entries based + # on membership of that group. + # + # Due to the potentially large expansions, rather than modify the + # list we are enumerating, we build a new one as we go. + # + + new_refs = [] + for r in refs: + if 'OS-INHERIT:inherited_to' in r['scope']: + # It's an inherited domain role - so get the list of projects + # owned by this domain. A domain scope is guaranteed since we + # checked this when we built the refs list + project_ids = ( + [x['id'] for x in self.assignment_api.list_projects( + r['scope']['domain']['id'])]) + base_entry = copy.deepcopy(r) + domain_id = base_entry['scope']['domain']['id'] + base_entry['scope'].pop('domain') + # For each project, create an equivalent role assignment + for p in project_ids: + # If it's a group assignment, then create equivalent user + # roles based on membership of the group + if 'group' in base_entry: + members = _get_group_members(base_entry) + sub_entry = copy.deepcopy(base_entry) + group_id = sub_entry['group']['id'] + sub_entry.pop('group') + for m in members: + new_entry = ( + _build_project_equivalent_of_group_domain_role( + m['id'], group_id, p, + domain_id, sub_entry)) + new_refs.append(new_entry) + else: + new_entry = ( + _build_project_equivalent_of_user_domain_role( + p, domain_id, base_entry)) + new_refs.append(new_entry) + elif 'group' in r: + # It's a non-inherited group role assignment, so get the list + # of members. + members = _get_group_members(r) + + # Now replace that group role assignment entry with an + # equivalent user role assignment for each of the group members + base_entry = copy.deepcopy(r) + group_id = base_entry['group']['id'] + base_entry.pop('group') + for m in members: + user_entry = _build_user_assignment_equivalent_of_group( + m, group_id, base_entry) + new_refs.append(user_entry) + else: + new_refs.append(r) + + return new_refs + + def _query_filter_is_true(self, filter_value): + """Determine if bool query param is 'True'. + + We treat this the same way as we do for policy + enforcement: + + {bool_param}=0 is treated as False + + Any other value is considered to be equivalent to + True, including the absence of a value + + """ + + if (isinstance(filter_value, basestring) and + filter_value == '0'): + val = False + else: + val = True + return val + + def _filter_inherited(self, entry): + if ('inherited_to_projects' in entry and + not CONF.os_inherit.enabled): + return False + else: + return True + + @controller.filterprotected('group.id', 'role.id', + 'scope.domain.id', 'scope.project.id', + 'scope.OS-INHERIT:inherited_to', 'user.id') + def list_role_assignments(self, context, filters): + + # TODO(henry-nash): This implementation uses the standard filtering + # in the V3.wrap_collection. Given the large number of individual + # assignments, this is pretty inefficient. An alternative would be + # to pass the filters into the driver call, so that the list size is + # kept a minimum. + + refs = self.identity_api.list_role_assignments() + formatted_refs = ( + [self._format_entity(x) for x in refs + if self._filter_inherited(x)]) + + if ('effective' in context['query_string'] and + self._query_filter_is_true( + context['query_string']['effective'])): + + formatted_refs = self._expand_indirect_assignments(formatted_refs) + + return self.wrap_collection(context, formatted_refs, filters) + + @controller.protected + def get_role_assignment(self, context): + raise exception.NotImplemented() + + @controller.protected + def update_role_assignment(self, context): + raise exception.NotImplemented() + + @controller.protected + def delete_role_assignment(self, context): + raise exception.NotImplemented() diff --git a/keystone/identity/core.py b/keystone/identity/core.py index a254470e..b2b3eaf0 100644 --- a/keystone/identity/core.py +++ b/keystone/identity/core.py @@ -52,6 +52,7 @@ def filter_user(user_ref): @dependency.provider('identity_api') +@dependency.requires('assignment_api') class Manager(manager.Manager): """Default pivot point for the Identity backend. @@ -63,15 +64,6 @@ class Manager(manager.Manager): def __init__(self): super(Manager, self).__init__(CONF.identity.driver) - def authenticate(self, user_id=None, tenant_id=None, password=None): - """Authenticate a given user and password and - authorize them for a tenant. - :returns: (user_ref, tenant_ref, metadata_ref) - :raises: AssertionError - """ - user_ref = self.driver.authenticate_user(user_id, password) - return self.driver.authorize_for_project(user_ref, tenant_id) - def create_user(self, user_id, user_ref): user = user_ref.copy() user['name'] = clean.user_name(user['name']) @@ -97,288 +89,133 @@ class Manager(manager.Manager): tenant.setdefault('enabled', True) tenant['enabled'] = clean.project_enabled(tenant['enabled']) tenant.setdefault('description', '') - return self.driver.create_project(tenant_id, tenant) + return self.assignment_api.create_project(tenant_id, tenant) def update_project(self, tenant_id, tenant_ref): tenant = tenant_ref.copy() if 'enabled' in tenant: tenant['enabled'] = clean.project_enabled(tenant['enabled']) - return self.driver.update_project(tenant_id, tenant) - - -class Driver(object): - """Interface description for an Identity driver.""" - - def authenticate_user(self, user_id, password): - """Authenticate a given user and password. - :returns: user_ref - :raises: AssertionError - """ - raise exception.NotImplemented() - - def authorize_for_project(self, tenant_id, user_ref): - """Authenticate a given user for a tenant. - :returns: (user_ref, tenant_ref, metadata_ref) - :raises: AssertionError - """ - raise exception.NotImplemented() + return self.assignment_api.update_project(tenant_id, tenant) def get_project_by_name(self, tenant_name, domain_id): - """Get a tenant by name. - - :returns: tenant_ref - :raises: keystone.exception.ProjectNotFound - - """ - raise exception.NotImplemented() - - def get_user_by_name(self, user_name, domain_id): - """Get a user by name. - - :returns: user_ref - :raises: keystone.exception.UserNotFound - - """ - raise exception.NotImplemented() - - def add_user_to_project(self, tenant_id, user_id): - """Add user to a tenant by creating a default role relationship. - - :raises: keystone.exception.ProjectNotFound, - keystone.exception.UserNotFound + return self.assignment_api.get_project_by_name(tenant_name, domain_id) - """ - self.add_role_to_user_and_project(user_id, - tenant_id, - config.CONF.member_role_id) - - def remove_user_from_project(self, tenant_id, user_id): - """Remove user from a tenant + def get_project(self, tenant_id): + return self.assignment_api.get_project(tenant_id) - :raises: keystone.exception.ProjectNotFound, - keystone.exception.UserNotFound + def list_projects(self, domain_id=None): + return self.assignment_api.list_projects(domain_id) - """ - roles = self.get_roles_for_user_and_project(user_id, tenant_id) - if not roles: - raise exception.NotFound(tenant_id) - for role_id in roles: - self.remove_role_from_user_and_project(user_id, tenant_id, role_id) - - def get_project_users(self, tenant_id): - """Lists all users with a relationship to the specified project. - - :returns: a list of user_refs or an empty set. - :raises: keystone.exception.ProjectNotFound + def get_role(self, role_id): + return self.assignment_api.get_role(role_id) - """ - raise exception.NotImplemented() + def list_roles(self): + return self.assignment_api.list_roles() def get_projects_for_user(self, user_id): - """Get the tenants associated with a given user. + return self.assignment_api.get_projects_for_user(user_id) - :returns: a list of tenant_id's. - :raises: keystone.exception.UserNotFound - - """ - raise exception.NotImplemented() + def get_project_users(self, tenant_id): + return self.assignment_api.get_project_users(tenant_id) def get_roles_for_user_and_project(self, user_id, tenant_id): - """Get the roles associated with a user within given tenant. - - :returns: a list of role ids. - :raises: keystone.exception.UserNotFound, - keystone.exception.ProjectNotFound - - """ - raise exception.NotImplemented() + return self.assignment_api.get_roles_for_user_and_project( + user_id, tenant_id) def get_roles_for_user_and_domain(self, user_id, domain_id): - """Get the roles associated with a user within given domain. - - :returns: a list of role ids. - :raises: keystone.exception.UserNotFound, - keystone.exception.ProjectNotFound - - """ - - def update_metadata_for_group_domain_roles(self, metadata_ref, - user_id, domain_id): - group_refs = self.list_groups_for_user(user_id=user_id) - for x in group_refs: - try: - metadata_ref.update( - self.get_metadata(group_id=x['id'], - domain_id=domain_id)) - except exception.MetadataNotFound: - # no group grant, skip - pass - - def update_metadata_for_user_domain_roles(self, metadata_ref, - user_id, domain_id): - try: - metadata_ref.update(self.get_metadata(user_id=user_id, - domain_id=domain_id)) - except exception.MetadataNotFound: - pass - - self.get_user(user_id) - self.get_domain(domain_id) - metadata_ref = {} - update_metadata_for_user_domain_roles(self, metadata_ref, - user_id, domain_id) - update_metadata_for_group_domain_roles(self, metadata_ref, - user_id, domain_id) - return list(set(metadata_ref.get('roles', []))) - - def add_role_to_user_and_project(self, user_id, tenant_id, role_id): - """Add a role to a user within given tenant. - - :raises: keystone.exception.UserNotFound, - keystone.exception.ProjectNotFound, - keystone.exception.RoleNotFound - """ - raise exception.NotImplemented() - - def remove_role_from_user_and_project(self, user_id, tenant_id, role_id): - """Remove a role from a user within given tenant. - - :raises: keystone.exception.UserNotFound, - keystone.exception.ProjectNotFound, - keystone.exception.RoleNotFound + return (self.assignment_api.get_roles_for_user_and_domain + (user_id, domain_id)) - """ - raise exception.NotImplemented() - - # metadata crud - def get_metadata(self, user_id=None, tenant_id=None, - domain_id=None, group_id=None): - """Gets the metadata for the specified user/group on project/domain. + def _subrole_id_to_dn(self, role_id, tenant_id): + return self.assignment_api._subrole_id_to_dn(role_id, tenant_id) - :raises: keystone.exception.MetadataNotFound - :returns: metadata - - """ - raise exception.NotImplemented() + def add_role_to_user_and_project(self, user_id, + tenant_id, role_id): + return (self.assignment_api.add_role_to_user_and_project + (user_id, tenant_id, role_id)) - def create_metadata(self, user_id, tenant_id, metadata, - domain_id=None, group_id=None): - """Creates the metadata for the specified user/group on project/domain. - - :returns: metadata created + def create_role(self, role_id, role): + return self.assignment_api.create_role(role_id, role) - """ - raise exception.NotImplemented() + def delete_role(self, role_id): + return self.assignment_api.delete_role(role_id) - def update_metadata(self, user_id, tenant_id, metadata, - domain_id=None, group_id=None): - """Updates the metadata for the specified user/group on project/domain. + def delete_project(self, tenant_id): + return self.assignment_api.delete_project(tenant_id) - :returns: metadata updated + def remove_role_from_user_and_project(self, user_id, + tenant_id, role_id): + return (self.assignment_api.remove_role_from_user_and_project + (user_id, tenant_id, role_id)) - """ - raise exception.NotImplemented() + def update_role(self, role_id, role): + return self.assignment_api.update_role(role_id, role) + + def create_grant(self, role_id, user_id=None, group_id=None, + domain_id=None, project_id=None, + inherited_to_projects=False): + return (self.assignment_api.create_grant + (role_id, user_id, group_id, domain_id, project_id, + inherited_to_projects)) + + def list_grants(self, user_id=None, group_id=None, + domain_id=None, project_id=None, + inherited_to_projects=False): + return (self.assignment_api.list_grants + (user_id, group_id, domain_id, project_id, + inherited_to_projects)) + + def get_grant(self, role_id, user_id=None, group_id=None, + domain_id=None, project_id=None, + inherited_to_projects=False): + return (self.assignment_api.get_grant + (role_id, user_id, group_id, domain_id, project_id, + inherited_to_projects)) + + def delete_grant(self, role_id, user_id=None, group_id=None, + domain_id=None, project_id=None, + inherited_to_projects=False): + return (self.assignment_api.delete_grant + (role_id, user_id, group_id, domain_id, project_id, + inherited_to_projects)) - # domain crud def create_domain(self, domain_id, domain): - """Creates a new domain. - - :raises: keystone.exception.Conflict - - """ - raise exception.NotImplemented() - - def list_domains(self): - """List all domains in the system. - - :returns: a list of domain_refs or an empty list. - - """ - raise exception.NotImplemented() - - def get_domain(self, domain_id): - """Get a domain by ID. - - :returns: domain_ref - :raises: keystone.exception.DomainNotFound - - """ - raise exception.NotImplemented() + return self.assignment_api.create_domain(domain_id, domain) def get_domain_by_name(self, domain_name): - """Get a domain by name. + return self.assignment_api.get_domain_by_name(domain_name) - :returns: domain_ref - :raises: keystone.exception.DomainNotFound - - """ - raise exception.NotImplemented() + def get_domain(self, domain_id): + return self.assignment_api.get_domain(domain_id) def update_domain(self, domain_id, domain): - """Updates an existing domain. - - :raises: keystone.exception.DomainNotFound, - keystone.exception.Conflict - - """ - raise exception.NotImplemented() + return self.assignment_api.update_domain(domain_id, domain) def delete_domain(self, domain_id): - """Deletes an existing domain. - - :raises: keystone.exception.DomainNotFound - - """ - raise exception.NotImplemented() + return self.assignment_api.delete_domain(domain_id) - # project crud - def create_project(self, project_id, project): - """Creates a new project. - - :raises: keystone.exception.Conflict - - """ - raise exception.NotImplemented() - - def list_projects(self): - """List all projects in the system. - - :returns: a list of project_refs or an empty list. - - """ - raise exception.NotImplemented() + def list_domains(self): + return self.assignment_api.list_domains() def list_user_projects(self, user_id): - """List all projects associated with a given user. + return self.assignment_api.list_user_projects(user_id) - :returns: a list of project_refs or an empty list. - - """ - raise exception.NotImplemented() - - def get_project(self, project_id): - """Get a project by ID. - - :returns: project_ref - :raises: keystone.exception.ProjectNotFound - - """ - raise exception.NotImplemented() - - def update_project(self, project_id, project): - """Updates an existing project. - - :raises: keystone.exception.ProjectNotFound, - keystone.exception.Conflict + def add_user_to_project(self, tenant_id, user_id): + return self.assignment_api.add_user_to_project(tenant_id, user_id) - """ - raise exception.NotImplemented() + def remove_user_from_project(self, tenant_id, user_id): + return self.assignment_api.remove_user_from_project(tenant_id, user_id) - def delete_project(self, project_id): - """Deletes an existing project. + def list_role_assignments(self): + return self.assignment_api.list_role_assignments() - :raises: keystone.exception.ProjectNotFound +class Driver(object): + """Interface description for an Identity driver.""" + def authenticate(self, user_id, password): + """Authenticate a given user and password. + :returns: user_ref + :raises: AssertionError """ raise exception.NotImplemented() @@ -460,46 +297,11 @@ class Driver(object): """ raise exception.NotImplemented() - # role crud - - def create_role(self, role_id, role): - """Creates a new role. - - :raises: keystone.exception.Conflict - - """ - raise exception.NotImplemented() - - def list_roles(self): - """List all roles in the system. - - :returns: a list of role_refs or an empty list. - - """ - raise exception.NotImplemented() - - def get_role(self, role_id): - """Get a role by ID. - - :returns: role_ref - :raises: keystone.exception.RoleNotFound - - """ - raise exception.NotImplemented() - - def update_role(self, role_id, role): - """Updates an existing role. - - :raises: keystone.exception.RoleNotFound, - keystone.exception.Conflict - - """ - raise exception.NotImplemented() - - def delete_role(self, role_id): - """Deletes an existing role. + def get_user_by_name(self, user_name, domain_id): + """Get a user by name. - :raises: keystone.exception.RoleNotFound + :returns: user_ref + :raises: keystone.exception.UserNotFound """ raise exception.NotImplemented() @@ -555,3 +357,7 @@ class Driver(object): """ raise exception.NotImplemented() + + #end of identity + + # Assignments diff --git a/keystone/identity/routers.py b/keystone/identity/routers.py index 32eada5e..5f236842 100644 --- a/keystone/identity/routers.py +++ b/keystone/identity/routers.py @@ -16,6 +16,7 @@ """WSGI Routers for the Identity service.""" from keystone.common import router from keystone.common import wsgi +from keystone import config from keystone.identity import controllers @@ -173,3 +174,48 @@ def append_v3_routers(mapper, routers): controller=role_controller, action='revoke_grant', conditions=dict(method=['DELETE'])) + + if config.CONF.os_inherit.enabled: + mapper.connect(('/OS-INHERIT/domains/{domain_id}/users/{user_id}' + '/roles/{role_id}/inherited_to_projects'), + controller=role_controller, + action='create_grant', + conditions=dict(method=['PUT'])) + mapper.connect(('/OS-INHERIT/domains/{domain_id}/groups/{group_id}' + '/roles/{role_id}/inherited_to_projects'), + controller=role_controller, + action='create_grant', + conditions=dict(method=['PUT'])) + mapper.connect(('/OS-INHERIT/domains/{domain_id}/users/{user_id}' + '/roles/{role_id}/inherited_to_projects'), + controller=role_controller, + action='check_grant', + conditions=dict(method=['HEAD'])) + mapper.connect(('/OS-INHERIT/domains/{domain_id}/groups/{group_id}' + '/roles/{role_id}/inherited_to_projects'), + controller=role_controller, + action='check_grant', + conditions=dict(method=['HEAD'])) + mapper.connect(('/OS-INHERIT/domains/{domain_id}/users/{user_id}' + '/roles/inherited_to_projects'), + controller=role_controller, + action='list_grants', + conditions=dict(method=['GET'])) + mapper.connect(('/OS-INHERIT/domains/{domain_id}/groups/{group_id}' + '/roles/inherited_to_projects'), + controller=role_controller, + action='list_grants', + conditions=dict(method=['GET'])) + mapper.connect(('/OS-INHERIT/domains/{domain_id}/users/{user_id}' + '/roles/{role_id}/inherited_to_projects'), + controller=role_controller, + action='revoke_grant', + conditions=dict(method=['DELETE'])) + mapper.connect(('/OS-INHERIT/domains/{domain_id}/groups/{group_id}' + '/roles/{role_id}/inherited_to_projects'), + controller=role_controller, + action='revoke_grant', + conditions=dict(method=['DELETE'])) + routers.append( + router.Router(controllers.RoleAssignmentV3(), + 'role_assignments', 'role_assignment')) diff --git a/keystone/locale/bg_BG/LC_MESSAGES/keystone.po b/keystone/locale/bg_BG/LC_MESSAGES/keystone.po index 13eb63b9..c6890424 100644 --- a/keystone/locale/bg_BG/LC_MESSAGES/keystone.po +++ b/keystone/locale/bg_BG/LC_MESSAGES/keystone.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2013-05-17 16:06+0000\n" "Last-Translator: openstackjenkins <jenkins@openstack.org>\n" "Language-Team: Bulgarian (Bulgaria) " @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,62 +38,224 @@ msgstr "" msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" msgstr "" -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" msgstr "" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 -#, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" #: keystone/catalog/core.py:38 @@ -120,18 +282,18 @@ msgstr "" msgid "Unable to open template file %s" msgstr "" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "" @@ -150,31 +312,31 @@ msgstr "" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "" @@ -183,33 +345,69 @@ msgstr "" msgid "Invalid token in normalize_domain_id" msgstr "" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "" -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "" @@ -242,13 +440,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "" -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "" @@ -436,12 +634,16 @@ msgstr "" msgid "Search scope %s not implemented." msgstr "" -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "" @@ -450,76 +652,68 @@ msgstr "" msgid "version should be an integer" msgstr "" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 -msgid "User not found in group" -msgstr "" - -#: keystone/identity/backends/sql.py:425 +#: keystone/identity/controllers.py:952 #, python-format -msgid "Cannot remove role that has not been granted, %s" +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:82 -#, python-format -msgid "Expected dict or list: %s" +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" msgstr "" -#: keystone/identity/backends/ldap/core.py:681 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Role %s not found" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -535,21 +729,56 @@ msgstr "" msgid "Failed to understand rule %(rule)r" msgstr "" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." msgstr "" #: keystone/token/backends/memcache.py:144 @@ -574,3 +803,54 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "" +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "" + +#~ msgid "User have no access to domain" +#~ msgstr "" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" + diff --git a/keystone/locale/bs/LC_MESSAGES/keystone.po b/keystone/locale/bs/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..8aee9ca5 --- /dev/null +++ b/keystone/locale/bs/LC_MESSAGES/keystone.po @@ -0,0 +1,848 @@ +# Bosnian translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: Bosnian " +"(http://www.transifex.com/projects/p/openstack/language/bs/)\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/ca/LC_MESSAGES/keystone.po b/keystone/locale/ca/LC_MESSAGES/keystone.po index c3c32221..110ea54c 100644 --- a/keystone/locale/ca/LC_MESSAGES/keystone.po +++ b/keystone/locale/ca/LC_MESSAGES/keystone.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2012-11-03 03:08+0000\n" "Last-Translator: Sergi Almacellas <pokoli@gmail.com>\n" "Language-Team: ca <LL@li.org>\n" @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,63 +38,224 @@ msgstr "" msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:333 -#, fuzzy, python-format -msgid "Unable to lookup user %s" -msgstr "No es pot afegir el token a la llista d'usuaris." - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" msgstr "" -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -#, fuzzy -msgid "Unable to sign token." +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, fuzzy, python-format +msgid "Unable to lookup user %s" msgstr "No es pot afegir el token a la llista d'usuaris." -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 -#, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" #: keystone/catalog/core.py:38 @@ -121,18 +282,18 @@ msgstr "" msgid "Unable to open template file %s" msgstr "" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "" @@ -151,31 +312,31 @@ msgstr "Fitxer syslog invà lid" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "" @@ -184,33 +345,69 @@ msgstr "" msgid "Invalid token in normalize_domain_id" msgstr "" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "" -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "" @@ -243,13 +440,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "" -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "" @@ -437,12 +634,16 @@ msgstr "" msgid "Search scope %s not implemented." msgstr "" -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "" @@ -451,76 +652,68 @@ msgstr "" msgid "version should be an integer" msgstr "" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 -msgid "User not found in group" -msgstr "" - -#: keystone/identity/backends/sql.py:425 +#: keystone/identity/controllers.py:952 #, python-format -msgid "Cannot remove role that has not been granted, %s" +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:82 -#, python-format -msgid "Expected dict or list: %s" +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" msgstr "" -#: keystone/identity/backends/ldap/core.py:681 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Role %s not found" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -536,21 +729,56 @@ msgstr "" msgid "Failed to understand rule %(rule)r" msgstr "" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." msgstr "" #: keystone/token/backends/memcache.py:144 @@ -575,3 +803,55 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "No es pot afegir el token a la llista de revocats." +#: keystone/token/providers/pki.py:43 +#, fuzzy +msgid "Unable to sign token." +msgstr "No es pot afegir el token a la llista d'usuaris." + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "" + +#~ msgid "User have no access to domain" +#~ msgstr "" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" + diff --git a/keystone/locale/cs/LC_MESSAGES/keystone.po b/keystone/locale/cs/LC_MESSAGES/keystone.po index 104e202c..75cddd40 100644 --- a/keystone/locale/cs/LC_MESSAGES/keystone.po +++ b/keystone/locale/cs/LC_MESSAGES/keystone.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2013-05-17 16:06+0000\n" "Last-Translator: openstackjenkins <jenkins@openstack.org>\n" "Language-Team: Czech " @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,62 +38,224 @@ msgstr "" msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" msgstr "" -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" msgstr "" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 -#, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" #: keystone/catalog/core.py:38 @@ -120,18 +282,18 @@ msgstr "" msgid "Unable to open template file %s" msgstr "" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "" @@ -150,31 +312,31 @@ msgstr "" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "" @@ -183,33 +345,69 @@ msgstr "" msgid "Invalid token in normalize_domain_id" msgstr "" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "" -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "" @@ -242,13 +440,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "" -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "" @@ -436,12 +634,16 @@ msgstr "" msgid "Search scope %s not implemented." msgstr "" -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "" @@ -450,76 +652,68 @@ msgstr "" msgid "version should be an integer" msgstr "" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 -msgid "User not found in group" -msgstr "" - -#: keystone/identity/backends/sql.py:425 +#: keystone/identity/controllers.py:952 #, python-format -msgid "Cannot remove role that has not been granted, %s" +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:82 -#, python-format -msgid "Expected dict or list: %s" +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" msgstr "" -#: keystone/identity/backends/ldap/core.py:681 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Role %s not found" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -535,21 +729,56 @@ msgstr "" msgid "Failed to understand rule %(rule)r" msgstr "" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." msgstr "" #: keystone/token/backends/memcache.py:144 @@ -574,3 +803,54 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "" +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "" + +#~ msgid "User have no access to domain" +#~ msgstr "" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" + diff --git a/keystone/locale/da/LC_MESSAGES/keystone.po b/keystone/locale/da/LC_MESSAGES/keystone.po index 83a0f31b..4243c60f 100644 --- a/keystone/locale/da/LC_MESSAGES/keystone.po +++ b/keystone/locale/da/LC_MESSAGES/keystone.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2013-05-17 16:06+0000\n" "Last-Translator: openstackjenkins <jenkins@openstack.org>\n" "Language-Team: Danish " @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,62 +38,224 @@ msgstr "" msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" msgstr "" -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" msgstr "" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 -#, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" #: keystone/catalog/core.py:38 @@ -120,18 +282,18 @@ msgstr "" msgid "Unable to open template file %s" msgstr "" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "" @@ -150,31 +312,31 @@ msgstr "" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "" @@ -183,33 +345,69 @@ msgstr "" msgid "Invalid token in normalize_domain_id" msgstr "" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "" -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "" @@ -242,13 +440,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "" -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "" @@ -436,12 +634,16 @@ msgstr "" msgid "Search scope %s not implemented." msgstr "" -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "" @@ -450,76 +652,68 @@ msgstr "" msgid "version should be an integer" msgstr "" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 -msgid "User not found in group" -msgstr "" - -#: keystone/identity/backends/sql.py:425 +#: keystone/identity/controllers.py:952 #, python-format -msgid "Cannot remove role that has not been granted, %s" +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:82 -#, python-format -msgid "Expected dict or list: %s" +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" msgstr "" -#: keystone/identity/backends/ldap/core.py:681 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Role %s not found" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -535,21 +729,56 @@ msgstr "" msgid "Failed to understand rule %(rule)r" msgstr "" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." msgstr "" #: keystone/token/backends/memcache.py:144 @@ -574,3 +803,54 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "" +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "" + +#~ msgid "User have no access to domain" +#~ msgstr "" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" + diff --git a/keystone/locale/de/LC_MESSAGES/keystone.po b/keystone/locale/de/LC_MESSAGES/keystone.po index 4d38a328..eb3b905d 100644 --- a/keystone/locale/de/LC_MESSAGES/keystone.po +++ b/keystone/locale/de/LC_MESSAGES/keystone.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2013-05-22 03:45+0000\n" "Last-Translator: daisy.ycguo <daisy.ycguo@gmail.com>\n" "Language-Team: German " @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,65 +38,225 @@ msgstr "%(property_name)s sollte nicht größer als %(max_length)s Zeichen sein. msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "%s wurde nicht ausgecheckt" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "Nicht gewährte Rolle kann nicht entfernt werden, %s" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "Rolle %s nicht gefunden" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "Projekt ist inaktiviert: %s" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "Domäne ist inaktiviert: %s" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "Benutzer ist inaktiviert: %s" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "Scoping sowohl auf 'domain' als auch auf 'project' ist nicht zulässig" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "Scoping sowohl auf 'domain' als auch auf 'trust' ist nicht zulässig" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "Scoping sowohl auf 'project' als auch auf 'trust' ist nicht zulässig" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "Suche nach Benutzer %s nicht möglich" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "Benutzer nicht gefunden" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" -msgstr "Benutzer hat keinen Zugriff auf Projekt" - -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "Benutzer hat keinen Zugriff auf Domäne" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." -msgstr "Token kann nicht unterzeichnet werden." +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 #, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +msgid "Unable to lookup user %s" +msgstr "Suche nach Benutzer %s nicht möglich" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" -"Ungültiger Wert für 'token_format': %s. Zulässige Werte sind PKI oder " -"UUID." #: keystone/catalog/core.py:38 #, python-format @@ -126,12 +286,12 @@ msgstr "" msgid "Unable to open template file %s" msgstr "Vorlagendatei %s kann nicht geöffnet werden" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "Fehler überprüfen: %s" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" @@ -139,7 +299,7 @@ msgstr "" "Unterzeichnungsfehler: Zertifikat kann nicht geladen werden - stellen Sie" " sicher, dass Sie PKI mit 'keystone-manage pki_setup' konfiguriert haben" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "Unterzeichnungsfehler: %s" @@ -158,31 +318,31 @@ msgstr "Ungültige 'syslog'-Funktion" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "Rollenbasierte Zugriffssteuerung: Ungültiges Token" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "Rollenbasierte Zugriffssteuerung: Ungültiger Benutzer" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "Rollenbasierte Zugriffssteuerung: Fortfahren ohne Projekt" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "Rollenbasierte Zugriffssteuerung: Fortsetzung ohne Nutzer" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "Rollenbasierte Zugriffssteuerung: Umgehen von Autorisierung" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "Rollenbasierte Zugriffssteuerung: Autorisierung erteilt" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "" @@ -193,33 +353,69 @@ msgstr "" msgid "Invalid token in normalize_domain_id" msgstr "Ungültiges Token in 'normalize_domain_id'" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "arg_dict: %s" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, fuzzy, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "Autorisierung fehlgeschlagen. %s von %s" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "Die Ressource konnte nicht gefunden werden." -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "Starten von %(arg0)s auf %(host)s:%(port)s" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "Serverfehler" @@ -252,13 +448,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "Doppelter Name, %s." -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "Doppelte ID, %s." @@ -452,14 +648,18 @@ msgstr "FakeLdap-Suche fehlgeschlagen: dn für 'SCOPE_BASE' nicht gefunden" msgid "Search scope %s not implemented." msgstr "Suchbereich %s nicht implementiert." -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "" "Es wurde festgestellt, dass keine Verbindung zum mysql-Server mehr " "vorhanden ist: %s" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "EC2-Berechtigungsnachweis kann nicht migriert werden: %s" @@ -468,76 +668,68 @@ msgstr "EC2-Berechtigungsnachweis kann nicht migriert werden: %s" msgid "version should be an integer" msgstr "Version sollte eine Ganzzahl sein" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "Nutzer %s erstellen" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "Benutzer %s erstellen" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, fuzzy, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "Benutzer %s zu Nutzer %s hinzufügen" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "Vorhandene Rolle %s ignorieren" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "Rolle %s erstellen" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, fuzzy, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "Rolle %s Benutzer %s auf Nutzer %s zuweisen" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, fuzzy, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "Erstellen von EC2-Berechtigungsnachweis für Benutzer %s und Nutzer %s" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 msgid "User not found in group" msgstr "Benutzer nicht in Gruppe gefunden" -#: keystone/identity/backends/sql.py:425 -#, python-format -msgid "Cannot remove role that has not been granted, %s" -msgstr "Nicht gewährte Rolle kann nicht entfernt werden, %s" - -#: keystone/identity/backends/ldap/core.py:82 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Expected dict or list: %s" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:681 -#, python-format -msgid "Role %s not found" -msgstr "Rolle %s nicht gefunden" - -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "Änderung von Namen wird von LDAP nicht unterstützt" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, fuzzy, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "Benutzer %s ist bereits Mitglied der Gruppe %s." -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -553,22 +745,57 @@ msgstr "Kein Handler für Ãœbereinstimmungen des Typs %s" msgid "Failed to understand rule %(rule)r" msgstr "Regel '%(rule)r' konnte nicht verstanden werden" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "Token gehört nicht zu angegebenem Nutzer." -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" -msgstr "Nicht-Standard-Domäne wird nicht unterstützt" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" -msgstr "Bereichsorientiertes Token der Domäne wird nicht unterstützt" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" #: keystone/token/backends/memcache.py:144 #, python-format @@ -592,3 +819,56 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "Token kann nicht zu Widerrufsliste hinzugefügt werden." +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "Token kann nicht unterzeichnet werden." + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "Nicht-Standard-Domäne wird nicht unterstützt" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "Bereichsorientiertes Token der Domäne wird nicht unterstützt" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "Benutzer hat keinen Zugriff auf Projekt" + +#~ msgid "User have no access to domain" +#~ msgstr "Benutzer hat keinen Zugriff auf Domäne" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" +#~ "Ungültiger Wert für 'token_format': %s. " +#~ "Zulässige Werte sind PKI oder UUID." + diff --git a/keystone/locale/en_AU/LC_MESSAGES/keystone.po b/keystone/locale/en_AU/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..65c1161c --- /dev/null +++ b/keystone/locale/en_AU/LC_MESSAGES/keystone.po @@ -0,0 +1,847 @@ +# English (Australia) translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: English (Australia) " +"(http://www.transifex.com/projects/p/openstack/language/en_AU/)\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/en_GB/LC_MESSAGES/keystone.po b/keystone/locale/en_GB/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..73b4dbef --- /dev/null +++ b/keystone/locale/en_GB/LC_MESSAGES/keystone.po @@ -0,0 +1,847 @@ +# English (United Kingdom) translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: English (United Kingdom) " +"(http://www.transifex.com/projects/p/openstack/language/en_GB/)\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/en_US/LC_MESSAGES/keystone.po b/keystone/locale/en_US/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..c440b653 --- /dev/null +++ b/keystone/locale/en_US/LC_MESSAGES/keystone.po @@ -0,0 +1,847 @@ +# English (United States) translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: English (United States) " +"(http://www.transifex.com/projects/p/openstack/language/en_US/)\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/es/LC_MESSAGES/keystone.po b/keystone/locale/es/LC_MESSAGES/keystone.po index 8cd820d9..b97acbc8 100644 --- a/keystone/locale/es/LC_MESSAGES/keystone.po +++ b/keystone/locale/es/LC_MESSAGES/keystone.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2013-05-21 09:13+0000\n" "Last-Translator: daisy.ycguo <daisy.ycguo@gmail.com>\n" "Language-Team: Spanish " @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,65 +38,225 @@ msgstr "%(property_name)s no debe tener más de %(max_length)s caracteres." msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "No se ha podido extraer %s" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "No se puede eliminar un rol que no se ha otorgado, %s" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "No se ha encontrado el rol %s" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "El proyecto está inhabilitado: %s" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "El dominio está inhabilitado: %s" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "El usuario está inhabilitado: %s" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "El ámbito para dominio y proyecto no está permitido" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "El ámbito para dominio y confianza no está permitido" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "El ámbito para proyecto y confianza no está permitido" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "No se ha podido buscar el usuario %s" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "Usuario no encontrado" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" -msgstr "El usuario no tiene acceso al proyecto" - -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "El usuario no tiene acceso al dominio" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." -msgstr "No se ha podido firmar la señal." +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 #, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +msgid "Unable to lookup user %s" +msgstr "No se ha podido buscar el usuario %s" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" -"Valor no válido para token_format: %s. Los valores permitidos son PKI o " -"UUID." #: keystone/catalog/core.py:38 #, python-format @@ -128,12 +288,12 @@ msgstr "" msgid "Unable to open template file %s" msgstr "No se puede abrir el archivo de plantilla %s" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "Verificar error: %s" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" @@ -141,7 +301,7 @@ msgstr "" "Error de firma: no se ha podido cargar el certificado; asegúrese de haber" " configurado la PKI con 'keystone-manage pki_setup'" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "Error de firma: %s" @@ -162,31 +322,31 @@ msgstr "Recurso syslog no válido" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "RBAC: Señal no válida" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "RBAC: Usuario no válido" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "RBAC: continuando sin proyecto" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "RBAC: Continuando sin arrendatario" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "RBAC: Eludiendo autorización" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "RBAC: Autorización otorgada" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "RBAC: añadiendo parámetros de filtro de consultas (%s)" @@ -195,33 +355,69 @@ msgstr "RBAC: añadiendo parámetros de filtro de consultas (%s)" msgid "Invalid token in normalize_domain_id" msgstr "Señal no válida en normalize_domain_id" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "arg_dict: %s" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, fuzzy, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "Ha fallado la autorización. %s de %s" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "El recurso no se ha podido encontrar." -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "Iniciando %(arg0)s en %(host)s:%(port)s" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "Error de servidor" @@ -254,13 +450,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "Nombre duplicado, %s." -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "ID duplicado, %s." @@ -461,12 +657,16 @@ msgstr "" msgid "Search scope %s not implemented." msgstr "Ãmbito de búsqueda %s no implementado." -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "Se ha notificado que mysql server ha desaparecido: %s" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "No se puede migrar la credencial EC2: %s " @@ -475,76 +675,68 @@ msgstr "No se puede migrar la credencial EC2: %s " msgid "version should be an integer" msgstr "la versión debe ser un entero" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "Crear el arrendatario %s" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "Crear el usuario %s" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, fuzzy, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "Añadir el usuario %s al arrendatario %s" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "Ignorando el rol existente %s" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "Crear el rol %s" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, fuzzy, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "Asignar el rol %s al usuario %s en el arrendatario %s" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, fuzzy, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "Creando credencial ec2 para el usuario %s y el arrendatario %s" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 msgid "User not found in group" msgstr "Usuario no encontrado en grupo" -#: keystone/identity/backends/sql.py:425 -#, python-format -msgid "Cannot remove role that has not been granted, %s" -msgstr "No se puede eliminar un rol que no se ha otorgado, %s" - -#: keystone/identity/backends/ldap/core.py:82 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Expected dict or list: %s" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:681 -#, python-format -msgid "Role %s not found" -msgstr "No se ha encontrado el rol %s" - -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "LDAP no soporta el cambio de nombre" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, fuzzy, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "El usuario %s ya es miembro del grupo %s" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -560,22 +752,57 @@ msgstr "No hay manejador para coincidencias de clase %s" msgid "Failed to understand rule %(rule)r" msgstr "No se ha podido comprender la regla %(rule)r" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "La señal no pertenece al arrendatario especificado." -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" -msgstr "El dominio no predeterminado no está soportado" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" -msgstr "La señal con ámbito de dominio no está soportada" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" #: keystone/token/backends/memcache.py:144 #, python-format @@ -599,3 +826,57 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "No se puede añadir señal a lista de revocación. " +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "No se ha podido firmar la señal." + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "El dominio no predeterminado no está soportado" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "La señal con ámbito de dominio no está soportada" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "El usuario no tiene acceso al proyecto" + +#~ msgid "User have no access to domain" +#~ msgstr "El usuario no tiene acceso al dominio" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" +#~ "Valor no válido para token_format: %s." +#~ " Los valores permitidos son PKI o " +#~ "UUID." + diff --git a/keystone/locale/fi_FI/LC_MESSAGES/keystone.po b/keystone/locale/fi_FI/LC_MESSAGES/keystone.po index cb839c03..cda26e08 100644 --- a/keystone/locale/fi_FI/LC_MESSAGES/keystone.po +++ b/keystone/locale/fi_FI/LC_MESSAGES/keystone.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2013-05-17 16:06+0000\n" "Last-Translator: openstackjenkins <jenkins@openstack.org>\n" "Language-Team: Finnish (Finland) " @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,62 +38,224 @@ msgstr "" msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" msgstr "" -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" msgstr "" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 -#, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" #: keystone/catalog/core.py:38 @@ -120,18 +282,18 @@ msgstr "" msgid "Unable to open template file %s" msgstr "" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "" @@ -150,31 +312,31 @@ msgstr "" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "" @@ -183,33 +345,69 @@ msgstr "" msgid "Invalid token in normalize_domain_id" msgstr "" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "" -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "" @@ -242,13 +440,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "" -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "" @@ -436,12 +634,16 @@ msgstr "" msgid "Search scope %s not implemented." msgstr "" -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "" @@ -450,76 +652,68 @@ msgstr "" msgid "version should be an integer" msgstr "" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 -msgid "User not found in group" -msgstr "" - -#: keystone/identity/backends/sql.py:425 +#: keystone/identity/controllers.py:952 #, python-format -msgid "Cannot remove role that has not been granted, %s" +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:82 -#, python-format -msgid "Expected dict or list: %s" +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" msgstr "" -#: keystone/identity/backends/ldap/core.py:681 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Role %s not found" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -535,21 +729,56 @@ msgstr "" msgid "Failed to understand rule %(rule)r" msgstr "" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." msgstr "" #: keystone/token/backends/memcache.py:144 @@ -574,3 +803,54 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "" +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "" + +#~ msgid "User have no access to domain" +#~ msgstr "" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" + diff --git a/keystone/locale/fr/LC_MESSAGES/keystone.po b/keystone/locale/fr/LC_MESSAGES/keystone.po index 048357e5..d2aced78 100644 --- a/keystone/locale/fr/LC_MESSAGES/keystone.po +++ b/keystone/locale/fr/LC_MESSAGES/keystone.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2013-05-17 16:06+0000\n" "Last-Translator: openstackjenkins <jenkins@openstack.org>\n" "Language-Team: French " @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,62 +38,224 @@ msgstr "" msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" msgstr "" -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" msgstr "" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 -#, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" #: keystone/catalog/core.py:38 @@ -120,18 +282,18 @@ msgstr "" msgid "Unable to open template file %s" msgstr "" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "" @@ -150,31 +312,31 @@ msgstr "" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "" @@ -183,33 +345,69 @@ msgstr "" msgid "Invalid token in normalize_domain_id" msgstr "" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "" -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "" @@ -242,13 +440,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "" -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "" @@ -436,12 +634,16 @@ msgstr "" msgid "Search scope %s not implemented." msgstr "" -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "" @@ -450,76 +652,68 @@ msgstr "" msgid "version should be an integer" msgstr "" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 -msgid "User not found in group" -msgstr "" - -#: keystone/identity/backends/sql.py:425 +#: keystone/identity/controllers.py:952 #, python-format -msgid "Cannot remove role that has not been granted, %s" +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:82 -#, python-format -msgid "Expected dict or list: %s" +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" msgstr "" -#: keystone/identity/backends/ldap/core.py:681 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Role %s not found" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -535,21 +729,56 @@ msgstr "" msgid "Failed to understand rule %(rule)r" msgstr "" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." msgstr "" #: keystone/token/backends/memcache.py:144 @@ -574,3 +803,54 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "" +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "" + +#~ msgid "User have no access to domain" +#~ msgstr "" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" + diff --git a/keystone/locale/hr/LC_MESSAGES/keystone.po b/keystone/locale/hr/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..8c5e03f5 --- /dev/null +++ b/keystone/locale/hr/LC_MESSAGES/keystone.po @@ -0,0 +1,848 @@ +# Croatian translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: Croatian " +"(http://www.transifex.com/projects/p/openstack/language/hr/)\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/hu/LC_MESSAGES/keystone.po b/keystone/locale/hu/LC_MESSAGES/keystone.po index c6443004..c8942c5b 100644 --- a/keystone/locale/hu/LC_MESSAGES/keystone.po +++ b/keystone/locale/hu/LC_MESSAGES/keystone.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2012-12-15 14:14+0000\n" "Last-Translator: kelemeng <kelemeng@gnome.hu>\n" "Language-Team: hu <LL@li.org>\n" @@ -17,7 +17,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -39,63 +39,224 @@ msgstr "%(property_name)s nem lehet több, mint %(max_length)s karakter." msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "%(property_name)s nem %(display_expected_type)s" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "Nem sikerült %s kiiktatása" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:333 -#, fuzzy, python-format -msgid "Unable to lookup user %s" -msgstr "Nem vehetÅ‘ fel a token felhasználólistája." - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" msgstr "" -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -#, fuzzy -msgid "Unable to sign token." +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, fuzzy, python-format +msgid "Unable to lookup user %s" msgstr "Nem vehetÅ‘ fel a token felhasználólistája." -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 -#, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" #: keystone/catalog/core.py:38 @@ -124,18 +285,18 @@ msgstr "Rosszul formázott végpont: %s hiányos formátum (hiányzik egy tÃpus msgid "Unable to open template file %s" msgstr "Nem nyitható meg a sablonfájl: %s" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "EllenÅ‘rzési hiba: %s" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "AláÃrási hiba: %s" @@ -154,31 +315,31 @@ msgstr "Érvénytelen rendszernapló szolgáltatás" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "" @@ -187,33 +348,69 @@ msgstr "" msgid "Invalid token in normalize_domain_id" msgstr "" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "arg_dict: %s" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, fuzzy, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "HitelesÃtés sikertelen. %s innen: %s" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "Az erÅ‘forrás nem található." -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "%(arg0)s indÃtása ezen: %(host)s:%(port)s" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "" @@ -246,13 +443,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "Többszörös név: %s." -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "Többszörös azonosÃtó: %s." @@ -444,12 +641,16 @@ msgstr "FakeLdap keresés sikertelen: a dn nem található a SCOPE_BASE-hez" msgid "Search scope %s not implemented." msgstr "A(z) %s keresési hatókör nincs megvalósÃtva." -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "A kapott MySQL szerver eltűnt: %s" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "Nem migrálhatók az EC2 hitelesÃtési adatok: %s" @@ -458,76 +659,68 @@ msgstr "Nem migrálhatók az EC2 hitelesÃtési adatok: %s" msgid "version should be an integer" msgstr "" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "%s bérlÅ‘ létrehozása" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "%s felhasználó létrehozása" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, fuzzy, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "%s felhasználó hozzáadása %s bérlÅ‘höz" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "MeglévÅ‘ %s szerep figyelmen kÃvül hagyása" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "%s szerep létrehozása" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, fuzzy, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "%s szerep hozzárendelése %s felhasználóhoz %s bérlÅ‘ben" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, fuzzy, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "EC2 hitelesÃtési adatok létrehozása %s felhasználóhoz és %s bérlÅ‘höz" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 -msgid "User not found in group" -msgstr "" - -#: keystone/identity/backends/sql.py:425 +#: keystone/identity/controllers.py:952 #, python-format -msgid "Cannot remove role that has not been granted, %s" +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:82 -#, python-format -msgid "Expected dict or list: %s" +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" msgstr "" -#: keystone/identity/backends/ldap/core.py:681 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Role %s not found" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -543,21 +736,56 @@ msgstr "" msgid "Failed to understand rule %(rule)r" msgstr "" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." msgstr "" #: keystone/token/backends/memcache.py:144 @@ -582,3 +810,55 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "A token nem adható a visszavonási listához." +#: keystone/token/providers/pki.py:43 +#, fuzzy +msgid "Unable to sign token." +msgstr "Nem vehetÅ‘ fel a token felhasználólistája." + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "" + +#~ msgid "User have no access to domain" +#~ msgstr "" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" + diff --git a/keystone/locale/id/LC_MESSAGES/keystone.po b/keystone/locale/id/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..1d5650b6 --- /dev/null +++ b/keystone/locale/id/LC_MESSAGES/keystone.po @@ -0,0 +1,847 @@ +# Indonesian translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: Indonesian " +"(http://www.transifex.com/projects/p/openstack/language/id/)\n" +"Plural-Forms: nplurals=1; plural=0\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/it/LC_MESSAGES/keystone.po b/keystone/locale/it/LC_MESSAGES/keystone.po index 7f3d7280..89f965ee 100644 --- a/keystone/locale/it/LC_MESSAGES/keystone.po +++ b/keystone/locale/it/LC_MESSAGES/keystone.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2013-05-17 16:06+0000\n" "Last-Translator: openstackjenkins <jenkins@openstack.org>\n" "Language-Team: Italian " @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,65 +38,225 @@ msgstr "%(property_name)s non può essere superiore a %(max_length)s caratteri." msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "Impossibile eseguire il checkout %s" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "Impossibile rimuovere un ruolo che non è stato concesso, %s" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "Ruolo %s non trovato" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "Il progetto è disabilitato: %s" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "Il dominio è disabilitato: %s" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "L'utente è disabilitato: %s" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "Il controllo sia del dominio che del progetto non è consentito" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "Il controllo sia del dominio che di trust non è consentito" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "Il controllo sia delprogetto che di trust non è consentito" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "Impossibile eseguire la ricerca dell'utente %s" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "Utente non trovato" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" -msgstr "L'utente non ha accesso al progetto" - -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "L'utente non ha accesso al dominio" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." -msgstr "Impossibile firmare il token." +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 #, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +msgid "Unable to lookup user %s" +msgstr "Impossibile eseguire la ricerca dell'utente %s" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" -"Valore non valido per token_format: %s. I valori consentiti sono PKI o " -"UUID." #: keystone/catalog/core.py:38 #, python-format @@ -126,12 +286,12 @@ msgstr "" msgid "Unable to open template file %s" msgstr "Impossibile aprire il file di template %s" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "Verifica errore: %s" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" @@ -139,7 +299,7 @@ msgstr "" "errore di firma: impossibile caricare il certificato - assicurarsi che " "sia stato configurato PKI con 'keystone-manage pki_setup'" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "Errore di firma: %s" @@ -158,31 +318,31 @@ msgstr "Funzione syslog non valida" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "RBAC: token non valido" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "RBAC: utente non valido" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "RBAC: si procede senza progetto" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "RBAC: si procede senza tenant" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "RBAC: autorizzazione oltrepassata" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "RBAC: autorizzazione concessa" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "RBAC: aggiunta parametri del filtro della query (%s)" @@ -191,33 +351,69 @@ msgstr "RBAC: aggiunta parametri del filtro della query (%s)" msgid "Invalid token in normalize_domain_id" msgstr "Token non valido in normalize_domain_id" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "arg_dict: %s" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, fuzzy, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "Autorizzazione non riuscita. %s da %s" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "Impossibile trovare la risorsa." -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "Avvio %(arg0)s in %(host)s:%(port)s" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "Errore del server" @@ -250,13 +446,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "Nome duplicato, %s." -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "ID duplicato, %s." @@ -450,12 +646,16 @@ msgstr "FakeLdap ricerca non riuscita: dn non trovato per SCOPE_BASE" msgid "Search scope %s not implemented." msgstr "Ambito di ricerca %s non implementato." -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "Ricevuto messaggio di interruzione della connessione del server mysql: %s" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "Impossibile migrare la credenziale EC2: %s" @@ -464,76 +664,68 @@ msgstr "Impossibile migrare la credenziale EC2: %s" msgid "version should be an integer" msgstr "la versione deve essere un numero intero" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "Crea tenant %s" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "Crea utente %s" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, fuzzy, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "Aggiungi utente %s al tenant %s" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "Il ruolo esistente viene ignorato %s" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "Crea ruolo %s" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, fuzzy, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "Assegna il ruolo %s all'utente %s nel tenant %s" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, fuzzy, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "Creazione credenziale ec2 per l'utente %s e del tenant %s" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 msgid "User not found in group" msgstr "Utente non trovato nel gruppo" -#: keystone/identity/backends/sql.py:425 -#, python-format -msgid "Cannot remove role that has not been granted, %s" -msgstr "Impossibile rimuovere un ruolo che non è stato concesso, %s" - -#: keystone/identity/backends/ldap/core.py:82 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Expected dict or list: %s" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:681 -#, python-format -msgid "Role %s not found" -msgstr "Ruolo %s non trovato" - -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "Modifica nome non supportato da LDAP" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, fuzzy, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "L'utente %s è già membro del gruppo %s" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -549,22 +741,57 @@ msgstr "Nessun gestore per le corrispondenze di tipo %s" msgid "Failed to understand rule %(rule)r" msgstr "Impossibile comprendere la regola %(rule)r" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "Il token non appartiene al tenant specificato." -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" -msgstr "Il dominio non predefinito non è supportato" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" -msgstr "L'ambito del dominio token non è supportato" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" #: keystone/token/backends/memcache.py:144 #, python-format @@ -588,3 +815,57 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "Impossibile aggiungere un token ad un elenco di revoca." +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "Impossibile firmare il token." + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "Il dominio non predefinito non è supportato" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "L'ambito del dominio token non è supportato" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "L'utente non ha accesso al progetto" + +#~ msgid "User have no access to domain" +#~ msgstr "L'utente non ha accesso al dominio" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" +#~ "Valore non valido per token_format: %s." +#~ " I valori consentiti sono PKI o " +#~ "UUID." + diff --git a/keystone/locale/it_IT/LC_MESSAGES/keystone.po b/keystone/locale/it_IT/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..7b8e76da --- /dev/null +++ b/keystone/locale/it_IT/LC_MESSAGES/keystone.po @@ -0,0 +1,847 @@ +# Italian (Italy) translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: Italian (Italy) " +"(http://www.transifex.com/projects/p/openstack/language/it_IT/)\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/ja/LC_MESSAGES/keystone.po b/keystone/locale/ja/LC_MESSAGES/keystone.po index 01c80b56..a8f0bb69 100644 --- a/keystone/locale/ja/LC_MESSAGES/keystone.po +++ b/keystone/locale/ja/LC_MESSAGES/keystone.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2012-11-03 01:25+0000\n" "Last-Translator: Tomoyuki KATO <tomo@dream.daynight.jp>\n" "Language-Team: Japanese " @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,63 +38,224 @@ msgstr "" msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:333 -#, fuzzy, python-format -msgid "Unable to lookup user %s" -msgstr "ユーザーリストã«ãƒˆãƒ¼ã‚¯ãƒ³ã‚’è¿½åŠ ã§ãã¾ã›ã‚“。" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" msgstr "" -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -#, fuzzy -msgid "Unable to sign token." +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, fuzzy, python-format +msgid "Unable to lookup user %s" msgstr "ユーザーリストã«ãƒˆãƒ¼ã‚¯ãƒ³ã‚’è¿½åŠ ã§ãã¾ã›ã‚“。" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 -#, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" #: keystone/catalog/core.py:38 @@ -121,18 +282,18 @@ msgstr "" msgid "Unable to open template file %s" msgstr "" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "" @@ -151,31 +312,31 @@ msgstr "無効㪠syslog ファシリティ" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "" @@ -184,33 +345,69 @@ msgstr "" msgid "Invalid token in normalize_domain_id" msgstr "" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "" -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "" @@ -243,13 +440,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "" -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "" @@ -437,12 +634,16 @@ msgstr "" msgid "Search scope %s not implemented." msgstr "" -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "" @@ -451,76 +652,68 @@ msgstr "" msgid "version should be an integer" msgstr "" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 -msgid "User not found in group" -msgstr "" - -#: keystone/identity/backends/sql.py:425 +#: keystone/identity/controllers.py:952 #, python-format -msgid "Cannot remove role that has not been granted, %s" +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:82 -#, python-format -msgid "Expected dict or list: %s" +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" msgstr "" -#: keystone/identity/backends/ldap/core.py:681 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Role %s not found" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -536,21 +729,56 @@ msgstr "" msgid "Failed to understand rule %(rule)r" msgstr "" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." msgstr "" #: keystone/token/backends/memcache.py:144 @@ -575,3 +803,55 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "失効リストã«ãƒˆãƒ¼ã‚¯ãƒ³ã‚’è¿½åŠ ã§ãã¾ã›ã‚“。" +#: keystone/token/providers/pki.py:43 +#, fuzzy +msgid "Unable to sign token." +msgstr "ユーザーリストã«ãƒˆãƒ¼ã‚¯ãƒ³ã‚’è¿½åŠ ã§ãã¾ã›ã‚“。" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "" + +#~ msgid "User have no access to domain" +#~ msgstr "" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" + diff --git a/keystone/locale/ka_GE/LC_MESSAGES/keystone.po b/keystone/locale/ka_GE/LC_MESSAGES/keystone.po index 283cee63..8d998614 100644 --- a/keystone/locale/ka_GE/LC_MESSAGES/keystone.po +++ b/keystone/locale/ka_GE/LC_MESSAGES/keystone.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2013-05-17 16:06+0000\n" "Last-Translator: openstackjenkins <jenkins@openstack.org>\n" "Language-Team: ka_GE <LL@li.org>\n" @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,62 +38,224 @@ msgstr "" msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "რáƒáƒšáƒ˜ %s ვერმáƒáƒ˜áƒ«áƒ”ბნáƒ" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "დáƒáƒ›áƒ”ნი გáƒáƒ—იშულიáƒ: %s" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "მáƒáƒ›áƒ®áƒ›áƒáƒ ებელი ვერმáƒáƒ˜áƒ«áƒ”ბნáƒ" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" -msgstr "მáƒáƒ›áƒ®áƒ›áƒáƒ ებელს áƒáƒ áƒáƒ¥áƒ•áƒ¡ წვდáƒáƒ›áƒ პრáƒáƒ”ქტზე" - -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" msgstr "" -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" msgstr "" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 -#, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" #: keystone/catalog/core.py:38 @@ -120,18 +282,18 @@ msgstr "" msgid "Unable to open template file %s" msgstr "" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "" @@ -150,31 +312,31 @@ msgstr "" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "" @@ -183,33 +345,69 @@ msgstr "" msgid "Invalid token in normalize_domain_id" msgstr "" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "" -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "" @@ -242,13 +440,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "" -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "" @@ -436,12 +634,16 @@ msgstr "" msgid "Search scope %s not implemented." msgstr "" -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "" @@ -450,76 +652,68 @@ msgstr "" msgid "version should be an integer" msgstr "" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "მáƒáƒ›áƒ®áƒ›áƒáƒ ებლის შექმნრ%s" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 -msgid "User not found in group" -msgstr "" - -#: keystone/identity/backends/sql.py:425 +#: keystone/identity/controllers.py:952 #, python-format -msgid "Cannot remove role that has not been granted, %s" +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:82 -#, python-format -msgid "Expected dict or list: %s" +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" msgstr "" -#: keystone/identity/backends/ldap/core.py:681 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Role %s not found" -msgstr "რáƒáƒšáƒ˜ %s ვერმáƒáƒ˜áƒ«áƒ”ბნáƒ" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -535,21 +729,56 @@ msgstr "" msgid "Failed to understand rule %(rule)r" msgstr "" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." msgstr "" #: keystone/token/backends/memcache.py:144 @@ -574,3 +803,54 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "" +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "მáƒáƒ›áƒ®áƒ›áƒáƒ ებელს áƒáƒ áƒáƒ¥áƒ•áƒ¡ წვდáƒáƒ›áƒ პრáƒáƒ”ქტზე" + +#~ msgid "User have no access to domain" +#~ msgstr "" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" + diff --git a/keystone/locale/keystone.pot b/keystone/locale/keystone.pot index 663e2f7f..718b35c8 100644 --- a/keystone/locale/keystone.pot +++ b/keystone/locale/keystone.pot @@ -7,16 +7,16 @@ msgid "" msgstr "" "Project-Id-Version: keystone " -"jenkins.keystone.propose.translation.update.234\n" +"jenkins.keystone.propose.translation.update.280\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,62 +38,224 @@ msgstr "" msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" msgstr "" -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" msgstr "" -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." -msgstr "" - -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 -#, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" #: keystone/catalog/core.py:38 @@ -120,18 +282,18 @@ msgstr "" msgid "Unable to open template file %s" msgstr "" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "" @@ -150,31 +312,31 @@ msgstr "" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "" @@ -183,33 +345,69 @@ msgstr "" msgid "Invalid token in normalize_domain_id" msgstr "" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "" -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "" @@ -242,13 +440,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "" -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "" @@ -436,12 +634,16 @@ msgstr "" msgid "Search scope %s not implemented." msgstr "" -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "" @@ -450,76 +652,68 @@ msgstr "" msgid "version should be an integer" msgstr "" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 -msgid "User not found in group" -msgstr "" - -#: keystone/identity/backends/sql.py:425 +#: keystone/identity/controllers.py:952 #, python-format -msgid "Cannot remove role that has not been granted, %s" +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:82 -#, python-format -msgid "Expected dict or list: %s" +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" msgstr "" -#: keystone/identity/backends/ldap/core.py:681 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Role %s not found" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -535,21 +729,56 @@ msgstr "" msgid "Failed to understand rule %(rule)r" msgstr "" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." msgstr "" #: keystone/token/backends/memcache.py:144 @@ -574,3 +803,45 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "" +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/ko/LC_MESSAGES/keystone.po b/keystone/locale/ko/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..cb047f5f --- /dev/null +++ b/keystone/locale/ko/LC_MESSAGES/keystone.po @@ -0,0 +1,847 @@ +# Korean translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: Korean " +"(http://www.transifex.com/projects/p/openstack/language/ko/)\n" +"Plural-Forms: nplurals=1; plural=0\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/ko_KR/LC_MESSAGES/keystone.po b/keystone/locale/ko_KR/LC_MESSAGES/keystone.po index d80557dd..733aef75 100644 --- a/keystone/locale/ko_KR/LC_MESSAGES/keystone.po +++ b/keystone/locale/ko_KR/LC_MESSAGES/keystone.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2013-03-21 18:34+0000\n" "Last-Translator: openstackjenkins <jenkins@openstack.org>\n" "Language-Team: ko_KR <LL@li.org>\n" @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,62 +38,224 @@ msgstr "" msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" msgstr "" -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" msgstr "" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 -#, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" #: keystone/catalog/core.py:38 @@ -120,18 +282,18 @@ msgstr "" msgid "Unable to open template file %s" msgstr "" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "" @@ -150,31 +312,31 @@ msgstr "" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "" @@ -183,33 +345,69 @@ msgstr "" msgid "Invalid token in normalize_domain_id" msgstr "" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "" -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "" @@ -242,13 +440,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "" -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "" @@ -436,12 +634,16 @@ msgstr "" msgid "Search scope %s not implemented." msgstr "" -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "" @@ -450,76 +652,68 @@ msgstr "" msgid "version should be an integer" msgstr "" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "Role %s ìƒì„±" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 -msgid "User not found in group" -msgstr "" - -#: keystone/identity/backends/sql.py:425 +#: keystone/identity/controllers.py:952 #, python-format -msgid "Cannot remove role that has not been granted, %s" +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:82 -#, python-format -msgid "Expected dict or list: %s" +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" msgstr "" -#: keystone/identity/backends/ldap/core.py:681 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Role %s not found" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -535,21 +729,56 @@ msgstr "" msgid "Failed to understand rule %(rule)r" msgstr "" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." msgstr "" #: keystone/token/backends/memcache.py:144 @@ -574,3 +803,54 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "" +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "" + +#~ msgid "User have no access to domain" +#~ msgstr "" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" + diff --git a/keystone/locale/ms/LC_MESSAGES/keystone.po b/keystone/locale/ms/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..576761b9 --- /dev/null +++ b/keystone/locale/ms/LC_MESSAGES/keystone.po @@ -0,0 +1,847 @@ +# Malay translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: Malay " +"(http://www.transifex.com/projects/p/openstack/language/ms/)\n" +"Plural-Forms: nplurals=1; plural=0\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/nb/LC_MESSAGES/keystone.po b/keystone/locale/nb/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..d7a13243 --- /dev/null +++ b/keystone/locale/nb/LC_MESSAGES/keystone.po @@ -0,0 +1,847 @@ +# Norwegian BokmÃ¥l translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: Norwegian BokmÃ¥l " +"(http://www.transifex.com/projects/p/openstack/language/nb/)\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/nl_NL/LC_MESSAGES/keystone.po b/keystone/locale/nl_NL/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..6bbb3ab3 --- /dev/null +++ b/keystone/locale/nl_NL/LC_MESSAGES/keystone.po @@ -0,0 +1,847 @@ +# Dutch (Netherlands) translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: Dutch (Netherlands) " +"(http://www.transifex.com/projects/p/openstack/language/nl_NL/)\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/pl_PL/LC_MESSAGES/keystone.po b/keystone/locale/pl_PL/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..1971b675 --- /dev/null +++ b/keystone/locale/pl_PL/LC_MESSAGES/keystone.po @@ -0,0 +1,857 @@ +# Polish (Poland) translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-06-28 06:06+0000\n" +"Last-Translator: daisy.ycguo <daisy.ycguo@gmail.com>\n" +"Language-Team: Polish (Poland) " +"(http://www.transifex.com/projects/p/openstack/language/pl_PL/)\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && " +"(n%100<10 || n%100>=20) ? 1 : 2)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "" + +#~ msgid "User have no access to domain" +#~ msgstr "" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" + diff --git a/keystone/locale/pt/LC_MESSAGES/keystone.po b/keystone/locale/pt/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..7f09b091 --- /dev/null +++ b/keystone/locale/pt/LC_MESSAGES/keystone.po @@ -0,0 +1,847 @@ +# Portuguese translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: Portuguese " +"(http://www.transifex.com/projects/p/openstack/language/pt/)\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/pt_BR/LC_MESSAGES/keystone.po b/keystone/locale/pt_BR/LC_MESSAGES/keystone.po index 61f81246..c580894d 100644 --- a/keystone/locale/pt_BR/LC_MESSAGES/keystone.po +++ b/keystone/locale/pt_BR/LC_MESSAGES/keystone.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2012-11-02 18:30+0000\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: Portuguese (Brazil) " @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,62 +38,224 @@ msgstr "" msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" msgstr "" -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" msgstr "" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 -#, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" #: keystone/catalog/core.py:38 @@ -120,18 +282,18 @@ msgstr "" msgid "Unable to open template file %s" msgstr "" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "" @@ -150,31 +312,31 @@ msgstr "" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "" @@ -183,33 +345,69 @@ msgstr "" msgid "Invalid token in normalize_domain_id" msgstr "" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "" -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "" @@ -242,13 +440,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "" -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "" @@ -436,12 +634,16 @@ msgstr "" msgid "Search scope %s not implemented." msgstr "" -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "" @@ -450,76 +652,68 @@ msgstr "" msgid "version should be an integer" msgstr "" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 -msgid "User not found in group" -msgstr "" - -#: keystone/identity/backends/sql.py:425 +#: keystone/identity/controllers.py:952 #, python-format -msgid "Cannot remove role that has not been granted, %s" +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:82 -#, python-format -msgid "Expected dict or list: %s" +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" msgstr "" -#: keystone/identity/backends/ldap/core.py:681 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Role %s not found" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -535,21 +729,56 @@ msgstr "" msgid "Failed to understand rule %(rule)r" msgstr "" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." msgstr "" #: keystone/token/backends/memcache.py:144 @@ -574,3 +803,54 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "" +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "" + +#~ msgid "User have no access to domain" +#~ msgstr "" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" + diff --git a/keystone/locale/ro/LC_MESSAGES/keystone.po b/keystone/locale/ro/LC_MESSAGES/keystone.po index f09a1178..b55073b6 100644 --- a/keystone/locale/ro/LC_MESSAGES/keystone.po +++ b/keystone/locale/ro/LC_MESSAGES/keystone.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2013-06-08 07:51+0000\n" "Last-Translator: daisy.ycguo <daisy.ycguo@gmail.com>\n" "Language-Team: Romanian " @@ -17,7 +17,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -39,62 +39,224 @@ msgstr "" msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" msgstr "" -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" msgstr "" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 -#, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" #: keystone/catalog/core.py:38 @@ -121,18 +283,18 @@ msgstr "" msgid "Unable to open template file %s" msgstr "" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "" @@ -151,31 +313,31 @@ msgstr "" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "" @@ -184,33 +346,69 @@ msgstr "" msgid "Invalid token in normalize_domain_id" msgstr "" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "" -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "" @@ -243,13 +441,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "" -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "" @@ -437,12 +635,16 @@ msgstr "" msgid "Search scope %s not implemented." msgstr "" -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "" @@ -451,76 +653,68 @@ msgstr "" msgid "version should be an integer" msgstr "" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 -msgid "User not found in group" -msgstr "" - -#: keystone/identity/backends/sql.py:425 +#: keystone/identity/controllers.py:952 #, python-format -msgid "Cannot remove role that has not been granted, %s" +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:82 -#, python-format -msgid "Expected dict or list: %s" +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" msgstr "" -#: keystone/identity/backends/ldap/core.py:681 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Role %s not found" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -536,21 +730,56 @@ msgstr "" msgid "Failed to understand rule %(rule)r" msgstr "" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." msgstr "" #: keystone/token/backends/memcache.py:144 @@ -575,3 +804,54 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "" +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "" + +#~ msgid "User have no access to domain" +#~ msgstr "" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" + diff --git a/keystone/locale/ru/LC_MESSAGES/keystone.po b/keystone/locale/ru/LC_MESSAGES/keystone.po index cbc74358..db8fe633 100644 --- a/keystone/locale/ru/LC_MESSAGES/keystone.po +++ b/keystone/locale/ru/LC_MESSAGES/keystone.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2013-05-17 16:06+0000\n" "Last-Translator: openstackjenkins <jenkins@openstack.org>\n" "Language-Team: Russian " @@ -17,7 +17,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -39,62 +39,224 @@ msgstr "" msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" msgstr "" -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" msgstr "" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 -#, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" #: keystone/catalog/core.py:38 @@ -121,18 +283,18 @@ msgstr "" msgid "Unable to open template file %s" msgstr "" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "" @@ -151,31 +313,31 @@ msgstr "" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "" @@ -184,33 +346,69 @@ msgstr "" msgid "Invalid token in normalize_domain_id" msgstr "" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "" -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "" @@ -243,13 +441,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "" -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "" @@ -437,12 +635,16 @@ msgstr "" msgid "Search scope %s not implemented." msgstr "" -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "" @@ -451,76 +653,68 @@ msgstr "" msgid "version should be an integer" msgstr "" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 -msgid "User not found in group" -msgstr "" - -#: keystone/identity/backends/sql.py:425 +#: keystone/identity/controllers.py:952 #, python-format -msgid "Cannot remove role that has not been granted, %s" +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:82 -#, python-format -msgid "Expected dict or list: %s" +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" msgstr "" -#: keystone/identity/backends/ldap/core.py:681 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Role %s not found" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -536,21 +730,56 @@ msgstr "" msgid "Failed to understand rule %(rule)r" msgstr "" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." msgstr "" #: keystone/token/backends/memcache.py:144 @@ -575,3 +804,54 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "" +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "" + +#~ msgid "User have no access to domain" +#~ msgstr "" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" + diff --git a/keystone/locale/ru_RU/LC_MESSAGES/keystone.po b/keystone/locale/ru_RU/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..4782ae4a --- /dev/null +++ b/keystone/locale/ru_RU/LC_MESSAGES/keystone.po @@ -0,0 +1,848 @@ +# Russian (Russia) translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: Russian (Russia) " +"(http://www.transifex.com/projects/p/openstack/language/ru_RU/)\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/sl_SI/LC_MESSAGES/keystone.po b/keystone/locale/sl_SI/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..8c044ca8 --- /dev/null +++ b/keystone/locale/sl_SI/LC_MESSAGES/keystone.po @@ -0,0 +1,857 @@ +# Slovenian (Slovenia) translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-06-28 06:06+0000\n" +"Last-Translator: daisy.ycguo <daisy.ycguo@gmail.com>\n" +"Language-Team: Slovenian (Slovenia) " +"(http://www.transifex.com/projects/p/openstack/language/sl_SI/)\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 " +"|| n%100==4 ? 2 : 3)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "" + +#~ msgid "User have no access to domain" +#~ msgstr "" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" + diff --git a/keystone/locale/sw_KE/LC_MESSAGES/keystone.po b/keystone/locale/sw_KE/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..f3a77803 --- /dev/null +++ b/keystone/locale/sw_KE/LC_MESSAGES/keystone.po @@ -0,0 +1,847 @@ +# Swahili (Kenya) translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: Swahili (Kenya) " +"(http://www.transifex.com/projects/p/openstack/language/sw_KE/)\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/tl/LC_MESSAGES/keystone.po b/keystone/locale/tl/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..b1186d54 --- /dev/null +++ b/keystone/locale/tl/LC_MESSAGES/keystone.po @@ -0,0 +1,847 @@ +# Filipino (Philippines) translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: Tagalog " +"(http://www.transifex.com/projects/p/openstack/language/tl/)\n" +"Plural-Forms: nplurals=2; plural=(n > 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/tr_TR/LC_MESSAGES/keystone.po b/keystone/locale/tr_TR/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..866c94eb --- /dev/null +++ b/keystone/locale/tr_TR/LC_MESSAGES/keystone.po @@ -0,0 +1,847 @@ +# Turkish (Turkey) translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: Turkish (Turkey) " +"(http://www.transifex.com/projects/p/openstack/language/tr_TR/)\n" +"Plural-Forms: nplurals=1; plural=0\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/uk/LC_MESSAGES/keystone.po b/keystone/locale/uk/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..4d8e5cef --- /dev/null +++ b/keystone/locale/uk/LC_MESSAGES/keystone.po @@ -0,0 +1,848 @@ +# Ukrainian translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: Ukrainian " +"(http://www.transifex.com/projects/p/openstack/language/uk/)\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/vi_VN/LC_MESSAGES/keystone.po b/keystone/locale/vi_VN/LC_MESSAGES/keystone.po index fd927b31..a7f3d30c 100644 --- a/keystone/locale/vi_VN/LC_MESSAGES/keystone.po +++ b/keystone/locale/vi_VN/LC_MESSAGES/keystone.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2013-05-17 16:06+0000\n" "Last-Translator: openstackjenkins <jenkins@openstack.org>\n" "Language-Team: Vietnamese (Viet Nam) " @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,62 +38,224 @@ msgstr "" msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" msgstr "" -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" msgstr "" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 -#, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" msgstr "" #: keystone/catalog/core.py:38 @@ -120,18 +282,18 @@ msgstr "" msgid "Unable to open template file %s" msgstr "" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "" @@ -150,31 +312,31 @@ msgstr "" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "" @@ -183,33 +345,69 @@ msgstr "" msgid "Invalid token in normalize_domain_id" msgstr "" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "" -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "" @@ -242,13 +440,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "" -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "" @@ -436,12 +634,16 @@ msgstr "" msgid "Search scope %s not implemented." msgstr "" -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "" @@ -450,76 +652,68 @@ msgstr "" msgid "version should be an integer" msgstr "" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 -msgid "User not found in group" -msgstr "" - -#: keystone/identity/backends/sql.py:425 +#: keystone/identity/controllers.py:952 #, python-format -msgid "Cannot remove role that has not been granted, %s" +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:82 -#, python-format -msgid "Expected dict or list: %s" +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" msgstr "" -#: keystone/identity/backends/ldap/core.py:681 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Role %s not found" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -535,21 +729,56 @@ msgstr "" msgid "Failed to understand rule %(rule)r" msgstr "" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." msgstr "" #: keystone/token/backends/memcache.py:144 @@ -574,3 +803,54 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "" +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "" + +#~ msgid "User have no access to domain" +#~ msgstr "" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "" + diff --git a/keystone/locale/zh_CN/LC_MESSAGES/keystone.po b/keystone/locale/zh_CN/LC_MESSAGES/keystone.po index a0f65cdd..8d69a376 100644 --- a/keystone/locale/zh_CN/LC_MESSAGES/keystone.po +++ b/keystone/locale/zh_CN/LC_MESSAGES/keystone.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2013-05-21 06:08+0000\n" "Last-Translator: daisy.ycguo <daisy.ycguo@gmail.com>\n" "Language-Team: Chinese (China) " @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,63 +38,225 @@ msgstr "%(property_name)s ä¸åº”该超过 %(max_length)s 个å—符。" msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "未能检出 %s" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "æ— æ³•é™¤åŽ»å°šæœªæŽˆäºˆçš„è§’è‰² %s" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "找ä¸åˆ°è§’色 %s" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "项目已ç¦ç”¨ï¼š%s" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "域已ç¦ç”¨ï¼š%s" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "用户已ç¦ç”¨ï¼š%s" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "ä¸å…许åŒæ—¶å°†ä½œç”¨åŸŸé™å®šåˆ°åŸŸå’Œé¡¹ç›®" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "ä¸å…许åŒæ—¶å°†ä½œç”¨åŸŸé™å®šåˆ°åŸŸå’Œä¿¡ä»»" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "ä¸å…许åŒæ—¶å°†ä½œç”¨åŸŸé™å®šåˆ°é¡¹ç›®å’Œä¿¡ä»»" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "æ— æ³•æŸ¥æ‰¾ç”¨æˆ· %s" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "找ä¸åˆ°ç”¨æˆ·" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" -msgstr "用户对项目没有任何访问æƒé™" - -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "用户对域没有任何访问æƒé™" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." -msgstr "æ— æ³•å¯¹ä»¤ç‰Œè¿›è¡Œç¾å。" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 #, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." -msgstr "token_format 的值 %s æ— æ•ˆã€‚å…许值是 PKI 或 UUID。" +msgid "Unable to lookup user %s" +msgstr "æ— æ³•æŸ¥æ‰¾ç”¨æˆ· %s" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" #: keystone/catalog/core.py:38 #, python-format @@ -120,18 +282,18 @@ msgstr "端点 %s çš„æ ¼å¼ä¸æ£ç¡® - æ ¼å¼ä¸å®Œæ•´ï¼ˆæ‚¨é—æ¼äº†ç±»åž‹é€šçŸ msgid "Unable to open template file %s" msgstr "æ— æ³•æ‰“å¼€æ¨¡æ¿æ–‡ä»¶ %s" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "å‘生验è¯é”™è¯¯ï¼š%s" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "å‘生ç¾åé”™è¯¯ï¼šæ— æ³•è£…å…¥è¯ä¹¦ - 请确ä¿æ‚¨å·²ä½¿ç”¨â€œkeystone-manage pki_setupâ€é…ç½® PKI" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "å‘生ç¾å错误:%s" @@ -150,31 +312,31 @@ msgstr "ç³»ç»Ÿæ—¥å¿—å·¥å…·æ— æ•ˆ" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "RBACï¼šä»¤ç‰Œæ— æ•ˆ" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "RBACï¼šç”¨æˆ·æ— æ•ˆ" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "RBAC:æ£åœ¨æ²¡æœ‰é¡¹ç›®çš„情况下继ç»" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "RBAC:æ£åœ¨æ²¡æœ‰ç§Ÿæˆ·çš„情况下继ç»" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "RBAC:æ£åœ¨ç»•è¿‡æŽˆæƒ" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "RBAC:已授予æƒé™" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "RBAC:æ£åœ¨æ·»åŠ 查询过滤器å‚æ•° (%s)" @@ -183,33 +345,69 @@ msgstr "RBAC:æ£åœ¨æ·»åŠ 查询过滤器å‚æ•° (%s)" msgid "Invalid token in normalize_domain_id" msgstr "normalize_domain_id ä¸çš„ä»¤ç‰Œæ— æ•ˆ" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "arg_dict:%s" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, fuzzy, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "授æƒå¤±è´¥ã€‚%s æ¥è‡ª %s" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "找ä¸åˆ°è¯¥èµ„æºã€‚" -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "æ£åœ¨ %(host)s:%(port)s 上å¯åŠ¨ %(arg0)s" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "æœåŠ¡å™¨é”™è¯¯" @@ -242,13 +440,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "å称 %s é‡å¤ã€‚" -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "æ ‡è¯† %s é‡å¤ã€‚" @@ -436,12 +634,16 @@ msgstr "FakeLdap search 失败:对于 SCOPE_BASE,找ä¸åˆ° dn" msgid "Search scope %s not implemented." msgstr "未实现æœç´¢èŒƒå›´ %s。" -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "mysql æœåŠ¡å™¨å·²ä¸å˜åœ¨ï¼š%s" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "æ— æ³•è¿ç§» EC2 å‡è¯ï¼š%s" @@ -450,76 +652,68 @@ msgstr "æ— æ³•è¿ç§» EC2 å‡è¯ï¼š%s" msgid "version should be an integer" msgstr "版本应该为整数" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "请创建租户 %s" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "请创建用户 %s" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, fuzzy, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "请将用户 %s æ·»åŠ è‡³ç§Ÿæˆ· %s" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "æ£åœ¨å¿½ç•¥çŽ°æœ‰è§’色 %s" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "请创建角色 %s" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, fuzzy, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "请将角色 %s 分é…给用户 %s(在租户 %s 上)" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, fuzzy, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "æ£åœ¨ä¸ºç”¨æˆ· %s 和租户 %s 创建 ec2 å‡è¯" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 msgid "User not found in group" msgstr "在组ä¸æ‰¾ä¸åˆ°ç”¨æˆ·" -#: keystone/identity/backends/sql.py:425 -#, python-format -msgid "Cannot remove role that has not been granted, %s" -msgstr "æ— æ³•é™¤åŽ»å°šæœªæŽˆäºˆçš„è§’è‰² %s" - -#: keystone/identity/backends/ldap/core.py:82 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Expected dict or list: %s" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:681 -#, python-format -msgid "Role %s not found" -msgstr "找ä¸åˆ°è§’色 %s" - -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "更改å称ä¸å— LDAP 支æŒ" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, fuzzy, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "用户 %s 已是组 %s çš„æˆå‘˜" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -535,22 +729,57 @@ msgstr "对于类型为 %s 的匹é…项,ä¸å˜åœ¨ä»»ä½•å¤„ç†ç¨‹åº" msgid "Failed to understand rule %(rule)r" msgstr "未能ç†è§£è§„则 %(rule)r" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "令牌ä¸å±žäºŽæŒ‡å®šçš„租户。" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" -msgstr "éžç¼ºçœåŸŸä¸å—支æŒ" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" -msgstr "作用域é™å®šåˆ°åŸŸçš„令牌ä¸å—支æŒ" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" #: keystone/token/backends/memcache.py:144 #, python-format @@ -574,3 +803,54 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "æ— æ³•å°†ä»¤ç‰Œæ·»åŠ è‡³æ’¤é”€åˆ—è¡¨ã€‚" +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "æ— æ³•å¯¹ä»¤ç‰Œè¿›è¡Œç¾å。" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "éžç¼ºçœåŸŸä¸å—支æŒ" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "作用域é™å®šåˆ°åŸŸçš„令牌ä¸å—支æŒ" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "用户对项目没有任何访问æƒé™" + +#~ msgid "User have no access to domain" +#~ msgstr "用户对域没有任何访问æƒé™" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "token_format 的值 %s æ— æ•ˆã€‚å…许值是 PKI 或 UUID。" + diff --git a/keystone/locale/zh_HK/LC_MESSAGES/keystone.po b/keystone/locale/zh_HK/LC_MESSAGES/keystone.po new file mode 100644 index 00000000..be48e5f5 --- /dev/null +++ b/keystone/locale/zh_HK/LC_MESSAGES/keystone.po @@ -0,0 +1,847 @@ +# Chinese (Traditional, Hong Kong SAR China) translations for keystone. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the keystone project. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Keystone\n" +"Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" +"PO-Revision-Date: 2013-07-29 22:01+0000\n" +"Last-Translator: openstackjenkins <jenkins@openstack.org>\n" +"Language-Team: Chinese (Hong Kong) " +"(http://www.transifex.com/projects/p/openstack/language/zh_HK/)\n" +"Plural-Forms: nplurals=1; plural=0\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 1.3\n" + +#: keystone/clean.py:23 +#, python-format +msgid "%s cannot be empty." +msgstr "" + +#: keystone/clean.py:25 +#, python-format +msgid "%(property_name)s cannot be less than %(min_length)s characters." +msgstr "" + +#: keystone/clean.py:29 +#, python-format +msgid "%(property_name)s should not be greater than %(max_length)s characters." +msgstr "" + +#: keystone/clean.py:36 +#, python-format +msgid "%(property_name)s is not a %(display_expected_type)s" +msgstr "" + +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + +#: keystone/test.py:117 +#, python-format +msgid "Failed to checkout %s" +msgstr "" + +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 +#, python-format +msgid "Project is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 +#, python-format +msgid "Domain is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 +#, python-format +msgid "User is disabled: %s" +msgstr "" + +#: keystone/auth/controllers.py:262 +msgid "Scoping to both domain and project is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:265 +msgid "Scoping to both domain and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:268 +msgid "Scoping to both project and trust is not allowed" +msgstr "" + +#: keystone/auth/controllers.py:353 +msgid "User not found" +msgstr "" + +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" + +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 +#, python-format +msgid "Unable to lookup user %s" +msgstr "" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" + +#: keystone/catalog/core.py:38 +#, python-format +msgid "Malformed endpoint %(url)s - unknown key %(keyerror)s" +msgstr "" + +#: keystone/catalog/core.py:43 +#, python-format +msgid "" +"Malformed endpoint %(url)s - unknown key %(keyerror)s(are you missing " +"brackets ?)" +msgstr "" + +#: keystone/catalog/core.py:49 +#, python-format +msgid "" +"Malformed endpoint %s - incomplete format (are you " +"missing a type notifier ?)" +msgstr "" + +#: keystone/catalog/backends/templated.py:109 +#, python-format +msgid "Unable to open template file %s" +msgstr "" + +#: keystone/common/cms.py:26 +#, python-format +msgid "Verify error: %s" +msgstr "" + +#: keystone/common/cms.py:118 +msgid "" +"Signing error: Unable to load certificate - ensure you've configured PKI " +"with 'keystone-manage pki_setup'" +msgstr "" + +#: keystone/common/cms.py:122 +#, python-format +msgid "Signing error: %s" +msgstr "" + +#: keystone/common/config.py:89 +#, python-format +msgid "Unable to locate specified logging config file: %s" +msgstr "" + +#: keystone/common/config.py:107 +msgid "Invalid syslog facility" +msgstr "" + +#: keystone/common/controller.py:18 +#, python-format +msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" +msgstr "" + +#: keystone/common/controller.py:25 +msgid "RBAC: Invalid token" +msgstr "" + +#: keystone/common/controller.py:39 keystone/common/controller.py:60 +msgid "RBAC: Invalid user" +msgstr "" + +#: keystone/common/controller.py:45 +msgid "RBAC: Proceeding without project" +msgstr "" + +#: keystone/common/controller.py:65 +msgid "RBAC: Proceeding without tenant" +msgstr "" + +#: keystone/common/controller.py:95 keystone/common/controller.py:146 +msgid "RBAC: Bypassing authorization" +msgstr "" + +#: keystone/common/controller.py:104 keystone/common/controller.py:144 +msgid "RBAC: Authorization granted" +msgstr "" + +#: keystone/common/controller.py:134 +#, python-format +msgid "RBAC: Adding query filter params (%s)" +msgstr "" + +#: keystone/common/controller.py:322 +msgid "Invalid token in normalize_domain_id" +msgstr "" + +#: keystone/common/utils.py:233 +msgid "" +"Error setting up the debug environment. Verify that the option --debug-" +"url has the format <host>:<port> and that a debugger processes is " +"listening on that port." +msgstr "" + +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 +#, python-format +msgid "arg_dict: %s" +msgstr "" + +#: keystone/common/wsgi.py:243 +#, python-format +msgid "Authorization failed. %(exception)s from %(remote_addr)s" +msgstr "" + +#: keystone/common/wsgi.py:487 +msgid "The resource could not be found." +msgstr "" + +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 +#, python-format +msgid "Starting %(arg0)s on %(host)s:%(port)s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:113 +msgid "Server error" +msgstr "" + +#: keystone/common/ldap/core.py:79 +#, python-format +msgid "Invalid LDAP deref option: %s. Choose one of: " +msgstr "" + +#: keystone/common/ldap/core.py:87 +#, python-format +msgid "Invalid LDAP TLS certs option: %(option). Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:99 +#, python-format +msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s" +msgstr "" + +#: keystone/common/ldap/core.py:189 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%s\". Format must be " +"<ldap_attribute>:<keystone_attribute>" +msgstr "" + +#: keystone/common/ldap/core.py:195 +#, python-format +msgid "" +"Invalid additional attribute mapping: \"%(item)s\". Value " +"\"%(attr_map)s\" must use one of %(keys)s." +msgstr "" + +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 +#, python-format +msgid "Duplicate name, %s." +msgstr "" + +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 +#, python-format +msgid "Duplicate ID, %s." +msgstr "" + +#: keystone/common/ldap/core.py:294 +#, python-format +msgid "LDAP %s create" +msgstr "" + +#: keystone/common/ldap/core.py:372 +#, python-format +msgid "LDAP %s update" +msgstr "" + +#: keystone/common/ldap/core.py:405 +#, python-format +msgid "LDAP %s delete" +msgstr "" + +#: keystone/common/ldap/core.py:430 +#, python-format +msgid "LDAP init: url=%s" +msgstr "" + +#: keystone/common/ldap/core.py:431 +#, python-format +msgid "" +"LDAP init: use_tls=%(use_tls)s\n" +"tls_cacertfile=%(tls_cacertfile)s\n" +"tls_cacertdir=%(tls_cacertdir)s\n" +"tls_req_cert=%(tls_req_cert)s\n" +"tls_avail=%(tls_avail)s\n" +msgstr "" + +#: keystone/common/ldap/core.py:450 +msgid "Invalid TLS / LDAPS combination" +msgstr "" + +#: keystone/common/ldap/core.py:454 +#, python-format +msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available" +msgstr "" + +#: keystone/common/ldap/core.py:464 +#, python-format +msgid "tls_cacertfile %s not found or is not a file" +msgstr "" + +#: keystone/common/ldap/core.py:476 +#, python-format +msgid "tls_cacertdir %s not found or is not a directory" +msgstr "" + +#: keystone/common/ldap/core.py:483 +#, python-format +msgid "LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s" +msgstr "" + +#: keystone/common/ldap/core.py:497 +#, python-format +msgid "LDAP bind: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:508 +#, python-format +msgid "LDAP add: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/core.py:514 +#, python-format +msgid "" +"LDAP search: dn=%(dn)s, scope=%(scope)s, query=%(query)s, " +"attrs=%(attrlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:567 +msgid "" +"LDAP Server does not support paging. Disable paging in keystone.conf to " +"avoid this message." +msgstr "" + +#: keystone/common/ldap/core.py:584 +#, python-format +msgid "LDAP modify: dn=%(dn)s, modlist=%(modlist)s" +msgstr "" + +#: keystone/common/ldap/core.py:590 +#, python-format +msgid "LDAP delete: dn=%s" +msgstr "" + +#: keystone/common/ldap/core.py:595 +#, python-format +msgid "LDAP delete_ext: dn=%(dn)s, serverctrls=%(serverctrls)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:146 +#, python-format +msgid "FakeLdap initialize url=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:156 +#, python-format +msgid "FakeLdap bind dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:163 +#, python-format +msgid "FakeLdap bind fail: dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:170 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s not found" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:175 +#, python-format +msgid "FakeLdap bind fail: password for dn=%s does not match" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:190 +#, python-format +msgid "FakeLdap add item: dn=%(dn)s, attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:193 +#, python-format +msgid "FakeLdap add item failed: dn=%s is already in store." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:207 keystone/common/ldap/fakeldap.py:221 +#, python-format +msgid "FakeLdap delete item: dn=%s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:211 keystone/common/ldap/fakeldap.py:225 +#, python-format +msgid "FakeLdap delete item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:240 +#, python-format +msgid "FakeLdap modify item: dn=%(dn)s attrs=%(attrs)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:245 +#, python-format +msgid "FakeLdap modify item failed: dn=%s not found." +msgstr "" + +#: keystone/common/ldap/fakeldap.py:262 +#, python-format +msgid "FakeLdap modify item failed: item has no attribute \"%s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:273 +#, python-format +msgid "" +"FakeLdap modify item failed: item has no attribute \"%(k)s\" with value " +"\"%(v)s\" to delete" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:279 +#, python-format +msgid "FakeLdap modify item failed: unknown command %s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:281 +#, python-format +msgid "modify_s action %s not implemented" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:300 +#, python-format +msgid "FakeLdap search at dn=%(dn)s scope=%(scope)s query=%(query)s" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:306 +msgid "FakeLdap search fail: dn not found for SCOPE_BASE" +msgstr "" + +#: keystone/common/ldap/fakeldap.py:320 +#, python-format +msgid "Search scope %s not implemented." +msgstr "" + +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 +#, python-format +msgid "Got mysql server has gone away: %s" +msgstr "" + +#: keystone/common/sql/legacy.py:188 +#, python-format +msgid "Cannot migrate EC2 credential: %s" +msgstr "" + +#: keystone/common/sql/migration.py:47 +msgid "version should be an integer" +msgstr "" + +#: keystone/common/sql/nova.py:65 +#, python-format +msgid "Create tenant %s" +msgstr "" + +#: keystone/common/sql/nova.py:82 +#, python-format +msgid "Create user %s" +msgstr "" + +#: keystone/common/sql/nova.py:91 +#, python-format +msgid "Add user %(user_id)s to tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:100 +#, python-format +msgid "Ignoring existing role %s" +msgstr "" + +#: keystone/common/sql/nova.py:107 +#, python-format +msgid "Create role %s" +msgstr "" + +#: keystone/common/sql/nova.py:117 +#, python-format +msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" +msgstr "" + +#: keystone/common/sql/nova.py:136 +#, python-format +msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" +msgstr "" + +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 +msgid "User not found in group" +msgstr "" + +#: keystone/identity/backends/ldap.py:189 +#, python-format +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." +msgstr "" + +#: keystone/identity/backends/ldap.py:334 +msgid "Changing Name not supported by LDAP" +msgstr "" + +#: keystone/identity/backends/ldap.py:347 +#, python-format +msgid "User %(user_id)s is already a member of group %(group_id)s" +msgstr "" + +#: keystone/openstack/common/policy.py:394 +#, python-format +msgid "Failed to understand rule %(rule)s" +msgstr "" + +#: keystone/openstack/common/policy.py:404 +#, python-format +msgid "No handler for matches of kind %s" +msgstr "" + +#: keystone/openstack/common/policy.py:679 +#, python-format +msgid "Failed to understand rule %(rule)r" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + +#: keystone/policy/backends/rules.py:93 +#, python-format +msgid "enforce %(action)s: %(credentials)s" +msgstr "" + +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 +msgid "Token does not belong to specified tenant." +msgstr "" + +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" + +#: keystone/token/backends/memcache.py:144 +#, python-format +msgid "" +"Successful set of token-index-list for user-key \"%(user_key)s\", " +"#%(count)d records" +msgstr "" + +#: keystone/token/backends/memcache.py:154 +#, python-format +msgid "" +"Failed to set token-index-list for user-key \"%(user_key)s\". Attempt " +"%(cas_retry)d of %(cas_retry_max)d" +msgstr "" + +#: keystone/token/backends/memcache.py:163 +msgid "Unable to add token user list" +msgstr "" + +#: keystone/token/backends/memcache.py:172 +msgid "Unable to add token to revocation list." +msgstr "" + +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + diff --git a/keystone/locale/zh_TW/LC_MESSAGES/keystone.po b/keystone/locale/zh_TW/LC_MESSAGES/keystone.po index eae36832..45af1114 100644 --- a/keystone/locale/zh_TW/LC_MESSAGES/keystone.po +++ b/keystone/locale/zh_TW/LC_MESSAGES/keystone.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Keystone\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n" -"POT-Creation-Date: 2013-06-17 17:09+0000\n" +"POT-Creation-Date: 2013-08-02 17:05+0000\n" "PO-Revision-Date: 2013-05-22 03:11+0000\n" "Last-Translator: daisy.ycguo <daisy.ycguo@gmail.com>\n" "Language-Team: Chinese (Taiwan) " @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" +"Generated-By: Babel 1.3\n" #: keystone/clean.py:23 #, python-format @@ -38,63 +38,225 @@ msgstr "%(property_name)s ä¸æ‡‰è¶…éŽ %(max_length)s 個å—元。" msgid "%(property_name)s is not a %(display_expected_type)s" msgstr "" +#: keystone/exception.py:48 +msgid "missing exception kwargs (programmer error)" +msgstr "" + +#: keystone/exception.py:65 +#, python-format +msgid "" +"Expecting to find %(attribute)s in %(target)s. The server could not " +"comply with the request since it is either malformed or otherwise " +"incorrect. The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:74 +#, python-format +msgid "" +"String length exceeded.The length of string '%(string)s' exceeded the " +"limit of column %(type)s(CHAR(%(length)d))." +msgstr "" + +#: keystone/exception.py:80 +#, python-format +msgid "" +"Request attribute %(attribute)s must be less than or equal to %(size)i. " +"The server could not comply with the request because the attribute size " +"is invalid (too large). The client is assumed to be in error." +msgstr "" + +#: keystone/exception.py:101 +msgid "The request you have made requires authentication." +msgstr "" + +#: keystone/exception.py:107 +msgid "Authentication plugin error." +msgstr "" + +#: keystone/exception.py:115 +msgid "Attempted to authenticate with an unsupported method." +msgstr "" + +#: keystone/exception.py:123 +msgid "Additional authentications steps required." +msgstr "" + +#: keystone/exception.py:131 +msgid "You are not authorized to perform the requested action." +msgstr "" + +#: keystone/exception.py:138 +#, python-format +msgid "You are not authorized to perform the requested action, %(action)s." +msgstr "" + +#: keystone/exception.py:143 +#, python-format +msgid "Could not find, %(target)s." +msgstr "" + +#: keystone/exception.py:149 +#, python-format +msgid "Could not find endpoint, %(endpoint_id)s." +msgstr "" + +#: keystone/exception.py:156 +msgid "An unhandled exception has occurred: Could not find metadata." +msgstr "" + +#: keystone/exception.py:161 +#, python-format +msgid "Could not find policy, %(policy_id)s." +msgstr "" + +#: keystone/exception.py:165 +#, python-format +msgid "Could not find role, %(role_id)s." +msgstr "" + +#: keystone/exception.py:169 +#, python-format +msgid "Could not find service, %(service_id)s." +msgstr "" + +#: keystone/exception.py:173 +#, python-format +msgid "Could not find domain, %(domain_id)s." +msgstr "" + +#: keystone/exception.py:177 +#, python-format +msgid "Could not find project, %(project_id)s." +msgstr "" + +#: keystone/exception.py:181 +#, python-format +msgid "Could not find token, %(token_id)s." +msgstr "" + +#: keystone/exception.py:185 +#, python-format +msgid "Could not find user, %(user_id)s." +msgstr "" + +#: keystone/exception.py:189 +#, python-format +msgid "Could not find group, %(group_id)s." +msgstr "" + +#: keystone/exception.py:193 +#, python-format +msgid "Could not find trust, %(trust_id)s." +msgstr "" + +#: keystone/exception.py:197 +#, python-format +msgid "Could not find credential, %(credential_id)s." +msgstr "" + +#: keystone/exception.py:201 +#, python-format +msgid "Could not find version, %(version)s." +msgstr "" + +#: keystone/exception.py:205 +#, python-format +msgid "Conflict occurred attempting to store %(type)s. %(details)s" +msgstr "" + +#: keystone/exception.py:212 +msgid "Request is too large." +msgstr "" + +#: keystone/exception.py:218 +#, python-format +msgid "" +"An unexpected error prevented the server from fulfilling your request. " +"%(exception)s" +msgstr "" + +#: keystone/exception.py:225 +#, python-format +msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details." +msgstr "" + +#: keystone/exception.py:230 +msgid "The action you have requested has not been implemented." +msgstr "" + +#: keystone/exception.py:237 +#, python-format +msgid "The Keystone paste configuration file %(config_file)s could not be found." +msgstr "" + #: keystone/test.py:117 #, python-format msgid "Failed to checkout %s" msgstr "無法移出 %s" -#: keystone/auth/controllers.py:72 +#: keystone/assignment/core.py:529 +#, python-format +msgid "Expected dict or list: %s" +msgstr "" + +#: keystone/assignment/backends/kvs.py:138 +#: keystone/assignment/backends/sql.py:285 +#, python-format +msgid "Cannot remove role that has not been granted, %s" +msgstr "無法移除尚未授權的角色,%s" + +#: keystone/assignment/backends/ldap.py:418 +#, python-format +msgid "Role %s not found" +msgstr "找ä¸åˆ°è§’色 %s" + +#: keystone/assignment/backends/sql.py:114 +msgid "Inherited roles can only be assigned to domains" +msgstr "" + +#: keystone/auth/controllers.py:71 #, python-format msgid "Project is disabled: %s" msgstr "å·²åœç”¨å°ˆæ¡ˆï¼š%s" -#: keystone/auth/controllers.py:78 keystone/auth/plugins/password.py:39 +#: keystone/auth/controllers.py:77 keystone/auth/plugins/password.py:38 #, python-format msgid "Domain is disabled: %s" msgstr "å·²åœç”¨ç¶²åŸŸï¼š%s" -#: keystone/auth/controllers.py:84 keystone/auth/plugins/password.py:45 +#: keystone/auth/controllers.py:83 keystone/auth/plugins/password.py:44 #, python-format msgid "User is disabled: %s" msgstr "å·²åœç”¨ä½¿ç”¨è€…:%s" -#: keystone/auth/controllers.py:265 +#: keystone/auth/controllers.py:262 msgid "Scoping to both domain and project is not allowed" msgstr "ä¸å®¹è¨±å°‡ç¯„åœåŒæ™‚è¨å®šç‚ºç¶²åŸŸåŠå°ˆæ¡ˆ" -#: keystone/auth/controllers.py:268 +#: keystone/auth/controllers.py:265 msgid "Scoping to both domain and trust is not allowed" msgstr "ä¸å®¹è¨±å°‡ç¯„åœåŒæ™‚è¨å®šç‚ºç¶²åŸŸåŠä¿¡ä»»" -#: keystone/auth/controllers.py:271 +#: keystone/auth/controllers.py:268 msgid "Scoping to both project and trust is not allowed" msgstr "ä¸å®¹è¨±å°‡ç¯„åœåŒæ™‚è¨å®šç‚ºå°ˆæ¡ˆåŠä¿¡ä»»" -#: keystone/auth/controllers.py:333 -#, python-format -msgid "Unable to lookup user %s" -msgstr "無法查閱使用者 %s" - -#: keystone/auth/controllers.py:363 +#: keystone/auth/controllers.py:353 msgid "User not found" msgstr "找ä¸åˆ°ä½¿ç”¨è€…" -#: keystone/auth/token_factory.py:81 -msgid "User have no access to project" -msgstr "使用者無法å˜å–專案" - -#: keystone/auth/token_factory.py:96 -msgid "User have no access to domain" -msgstr "使用者無法å˜å–網域" - -#: keystone/auth/token_factory.py:314 keystone/token/controllers.py:121 -msgid "Unable to sign token." -msgstr "無法簽署記號。" +#: keystone/auth/plugins/external.py:36 keystone/auth/plugins/external.py:66 +msgid "No authenticated user" +msgstr "" -#: keystone/auth/token_factory.py:317 keystone/token/controllers.py:124 +#: keystone/auth/plugins/external.py:49 keystone/auth/plugins/external.py:86 #, python-format -msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." -msgstr "token_format 的值無效:%s。接å—的值為 PKI 或 UUID。" +msgid "Unable to lookup user %s" +msgstr "無法查閱使用者 %s" + +#: keystone/auth/plugins/password.py:112 +msgid "Invalid username or password" +msgstr "" #: keystone/catalog/core.py:38 #, python-format @@ -120,18 +282,18 @@ msgstr "端點 %s çš„æ ¼å¼ä¸æ£ç¢º - æ ¼å¼ä¸å®Œæ•´ï¼ˆéºæ¼äº†é¡žåž‹é€šçŸ¥ç¬ msgid "Unable to open template file %s" msgstr "無法開啟範本檔 %s" -#: keystone/common/cms.py:42 +#: keystone/common/cms.py:26 #, python-format msgid "Verify error: %s" msgstr "é©—è‰ç™¼ç”ŸéŒ¯èª¤ï¼š%s" -#: keystone/common/cms.py:134 +#: keystone/common/cms.py:118 msgid "" "Signing error: Unable to load certificate - ensure you've configured PKI " "with 'keystone-manage pki_setup'" msgstr "ç°½ç½²ç™¼ç”ŸéŒ¯èª¤ï¼šç„¡æ³•è¼‰å…¥æ†‘è‰ - 請確ä¿å·²ä½¿ç”¨ 'keystone-manage pki_setup' 來é…ç½® PKI" -#: keystone/common/cms.py:138 +#: keystone/common/cms.py:122 #, python-format msgid "Signing error: %s" msgstr "簽署發生錯誤:%s" @@ -150,31 +312,31 @@ msgstr "無效的 Syslog 機能" msgid "RBAC: Authorizing %(action)s(%(kwargs)s)" msgstr "" -#: keystone/common/controller.py:26 +#: keystone/common/controller.py:25 msgid "RBAC: Invalid token" msgstr "RBAC:無效的記號" -#: keystone/common/controller.py:36 keystone/common/controller.py:57 +#: keystone/common/controller.py:39 keystone/common/controller.py:60 msgid "RBAC: Invalid user" msgstr "RBAC:無效的使用者" -#: keystone/common/controller.py:42 +#: keystone/common/controller.py:45 msgid "RBAC: Proceeding without project" msgstr "RBAC:在沒有專案的情æ³ä¸‹ç¹¼çºŒä½œæ¥" -#: keystone/common/controller.py:62 +#: keystone/common/controller.py:65 msgid "RBAC: Proceeding without tenant" msgstr "RBAC:在沒有 Tenant 的情æ³ä¸‹ç¹¼çºŒä½œæ¥" -#: keystone/common/controller.py:92 keystone/common/controller.py:144 +#: keystone/common/controller.py:95 keystone/common/controller.py:146 msgid "RBAC: Bypassing authorization" msgstr "RBAC:æ£åœ¨ç•¥éŽæŽˆæ¬Š" -#: keystone/common/controller.py:101 keystone/common/controller.py:142 +#: keystone/common/controller.py:104 keystone/common/controller.py:144 msgid "RBAC: Authorization granted" msgstr "RBAC:已授與權é™" -#: keystone/common/controller.py:131 +#: keystone/common/controller.py:134 #, python-format msgid "RBAC: Adding query filter params (%s)" msgstr "RBAC:æ£åœ¨æ–°å¢žæŸ¥è©¢éŽæ¿¾å™¨åƒæ•¸ (%s)" @@ -183,33 +345,69 @@ msgstr "RBAC:æ£åœ¨æ–°å¢žæŸ¥è©¢éŽæ¿¾å™¨åƒæ•¸ (%s)" msgid "Invalid token in normalize_domain_id" msgstr "normalize_domain_id ä¸çš„記號無效" -#: keystone/common/utils.py:232 +#: keystone/common/utils.py:233 msgid "" "Error setting up the debug environment. Verify that the option --debug-" "url has the format <host>:<port> and that a debugger processes is " "listening on that port." msgstr "" -#: keystone/common/wsgi.py:162 +#: keystone/common/wsgi.py:95 +msgid "No bind information present in token" +msgstr "" + +#: keystone/common/wsgi.py:99 +#, python-format +msgid "Named bind mode %s not in bind information" +msgstr "" + +#: keystone/common/wsgi.py:105 +msgid "Kerberos credentials required and not present" +msgstr "" + +#: keystone/common/wsgi.py:109 +msgid "Kerberos credentials do not match those in bind" +msgstr "" + +#: keystone/common/wsgi.py:112 +msgid "Kerberos bind authentication successful" +msgstr "" + +#: keystone/common/wsgi.py:115 +#, python-format +msgid "Ignoring unknown bind for permissive mode: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:119 +#, python-format +msgid "Couldn't verify unknown bind: {%(bind_type)s: %(identifier)s}" +msgstr "" + +#: keystone/common/wsgi.py:211 #, python-format msgid "arg_dict: %s" msgstr "arg_dict:%s" -#: keystone/common/wsgi.py:186 +#: keystone/common/wsgi.py:243 #, fuzzy, python-format msgid "Authorization failed. %(exception)s from %(remote_addr)s" msgstr "授權失敗。%s(自 %s)" -#: keystone/common/wsgi.py:429 +#: keystone/common/wsgi.py:487 msgid "The resource could not be found." msgstr "找ä¸åˆ°è³‡æºã€‚" -#: keystone/common/wsgi_server.py:72 +#: keystone/common/environment/__init__.py:37 +#, python-format +msgid "Environment configured as: %s" +msgstr "" + +#: keystone/common/environment/eventlet_server.py:51 #, python-format msgid "Starting %(arg0)s on %(host)s:%(port)s" msgstr "æ£åœ¨ %(host)s:%(port)s 上啟動 %(arg0)s" -#: keystone/common/wsgi_server.py:132 +#: keystone/common/environment/eventlet_server.py:113 msgid "Server error" msgstr "伺æœå™¨éŒ¯èª¤" @@ -242,13 +440,13 @@ msgid "" "\"%(attr_map)s\" must use one of %(keys)s." msgstr "" -#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:596 -#: keystone/identity/backends/kvs.py:624 +#: keystone/common/ldap/core.py:279 keystone/identity/backends/kvs.py:177 +#: keystone/identity/backends/kvs.py:205 #, python-format msgid "Duplicate name, %s." msgstr "é‡è¤‡çš„å稱,%s。" -#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:589 +#: keystone/common/ldap/core.py:289 keystone/identity/backends/kvs.py:170 #, python-format msgid "Duplicate ID, %s." msgstr "é‡è¤‡çš„ ID,%s。" @@ -436,12 +634,16 @@ msgstr "FakeLdap æœå°‹å¤±æ•—:找ä¸åˆ° SCOPE_BASE çš„ DN" msgid "Search scope %s not implemented." msgstr "未實作æœå°‹ç¯„åœ %s。" -#: keystone/common/sql/core.py:205 +#: keystone/common/sql/core.py:119 +msgid "Global engine callback raised." +msgstr "" + +#: keystone/common/sql/core.py:233 #, python-format msgid "Got mysql server has gone away: %s" msgstr "å·²å–å¾— mysql 伺æœå™¨å·²æ–·ç·šçš„訊æ¯ï¼š%s" -#: keystone/common/sql/legacy.py:180 +#: keystone/common/sql/legacy.py:188 #, python-format msgid "Cannot migrate EC2 credential: %s" msgstr "無法移轉 EC2 èªè‰ï¼š%s" @@ -450,76 +652,68 @@ msgstr "無法移轉 EC2 èªè‰ï¼š%s" msgid "version should be an integer" msgstr "版本應該是整數" -#: keystone/common/sql/nova.py:62 +#: keystone/common/sql/nova.py:65 #, python-format msgid "Create tenant %s" msgstr "建立 Tenant %s" -#: keystone/common/sql/nova.py:79 +#: keystone/common/sql/nova.py:82 #, python-format msgid "Create user %s" msgstr "建立使用者 %s" -#: keystone/common/sql/nova.py:88 +#: keystone/common/sql/nova.py:91 #, fuzzy, python-format msgid "Add user %(user_id)s to tenant %(tenant_id)s" msgstr "將使用者 %s 新增至 Tenant %s" -#: keystone/common/sql/nova.py:97 +#: keystone/common/sql/nova.py:100 #, python-format msgid "Ignoring existing role %s" msgstr "æ£åœ¨å¿½ç•¥ç¾æœ‰è§’色 %s" -#: keystone/common/sql/nova.py:104 +#: keystone/common/sql/nova.py:107 #, python-format msgid "Create role %s" msgstr "建立角色 %s" -#: keystone/common/sql/nova.py:114 +#: keystone/common/sql/nova.py:117 #, fuzzy, python-format msgid "Assign role %(role_id)s to user %(user_id)s on tenant %(tenant_id)s" msgstr "將角色 %s 指派給使用者 %s(在 Tenant %s 上)" -#: keystone/common/sql/nova.py:133 +#: keystone/common/sql/nova.py:136 #, fuzzy, python-format msgid "Creating ec2 cred for user %(user_id)s and tenant %(tenant_id)s" msgstr "æ£åœ¨çµ¦ä½¿ç”¨è€… %s åŠ Tenant %s 建立 EC2 Cred" -#: keystone/identity/backends/kvs.py:250 keystone/identity/backends/kvs.py:259 +#: keystone/identity/controllers.py:952 +#, python-format +msgid "" +"Group %(group)s not found for role-assignment - %(target)s with Role: " +"%(role)s" +msgstr "" + +#: keystone/identity/backends/kvs.py:126 keystone/identity/backends/kvs.py:135 msgid "User not found in group" msgstr "在群組ä¸æ‰¾ä¸åˆ°ä½¿ç”¨è€…" -#: keystone/identity/backends/sql.py:425 -#, python-format -msgid "Cannot remove role that has not been granted, %s" -msgstr "無法移除尚未授權的角色,%s" - -#: keystone/identity/backends/ldap/core.py:82 +#: keystone/identity/backends/ldap.py:189 #, python-format -msgid "Expected dict or list: %s" +msgid "" +"Group member '%(user_dn)s' not found in '%(group_id)s'. The user should " +"be removed from the group. The user will be ignored." msgstr "" -#: keystone/identity/backends/ldap/core.py:681 -#, python-format -msgid "Role %s not found" -msgstr "找ä¸åˆ°è§’色 %s" - -#: keystone/identity/backends/ldap/core.py:898 +#: keystone/identity/backends/ldap.py:334 msgid "Changing Name not supported by LDAP" msgstr "LDAP ä¸æ”¯æ´è®Šæ›´å稱" -#: keystone/identity/backends/ldap/core.py:911 +#: keystone/identity/backends/ldap.py:347 #, fuzzy, python-format msgid "User %(user_id)s is already a member of group %(group_id)s" msgstr "使用者 %s 已是群組 %s çš„æˆå“¡" -#: keystone/identity/backends/ldap/core.py:954 -#, python-format -msgid "" -"Group member '%(user_dn)s' not found in '%(group_dn)s'. The user should " -"be removed from the group. The user will be ignored." -msgstr "" - #: keystone/openstack/common/policy.py:394 #, python-format msgid "Failed to understand rule %(rule)s" @@ -535,22 +729,57 @@ msgstr "類型為 %s çš„ç›¸ç¬¦é …æ²’æœ‰è™•ç†ç¨‹å¼" msgid "Failed to understand rule %(rule)r" msgstr "無法ç†è§£è¦å‰‡ %(rule)r" +#: keystone/openstack/common/crypto/utils.py:29 +msgid "An unknown error occurred in crypto utils." +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:36 +#, python-format +msgid "Block size of %(given)d is too big, max = %(maximum)d" +msgstr "" + +#: keystone/openstack/common/crypto/utils.py:45 +#, python-format +msgid "Length of %(given)d is too long, max = %(maximum)d" +msgstr "" + #: keystone/policy/backends/rules.py:93 #, python-format msgid "enforce %(action)s: %(credentials)s" msgstr "" -#: keystone/token/controllers.py:465 keystone/token/controllers.py:468 +#: keystone/token/controllers.py:378 +#, python-format +msgid "User %(u_id)s is unauthorized for tenant %(t_id)s" +msgstr "" + +#: keystone/token/controllers.py:395 keystone/token/controllers.py:398 msgid "Token does not belong to specified tenant." msgstr "記號ä¸å±¬æ–¼æ‰€æŒ‡å®šçš„ Tenant。" -#: keystone/token/controllers.py:475 -msgid "Non-default domain is not supported" -msgstr "ä¸æ”¯æ´éžé è¨ç¶²åŸŸ" +#: keystone/token/provider.py:76 +msgid "" +"keystone.conf [signing] token_format (deprecated) conflicts with " +"keystone.conf [token] provider" +msgstr "" -#: keystone/token/controllers.py:483 -msgid "Domain scoped token is not supported" -msgstr "ä¸æ”¯æ´ç¶²åŸŸç¯„åœçš„記號" +#: keystone/token/provider.py:84 +msgid "" +"keystone.conf [signing] token_format is deprecated in favor of " +"keystone.conf [token] provider" +msgstr "" + +#: keystone/token/provider.py:94 +msgid "" +"Unrecognized keystone.conf [signing] token_format: expected either 'UUID'" +" or 'PKI'" +msgstr "" + +#: keystone/token/backends/kvs.py:37 +msgid "" +"kvs token backend is DEPRECATED. Use keystone.token.backends.sql or " +"keystone.token.backend.memcache instead." +msgstr "" #: keystone/token/backends/memcache.py:144 #, python-format @@ -574,3 +803,54 @@ msgstr "" msgid "Unable to add token to revocation list." msgstr "無法將記號新增至撤銷清冊。" +#: keystone/token/providers/pki.py:43 +msgid "Unable to sign token." +msgstr "無法簽署記號。" + +#: keystone/token/providers/uuid.py:193 +msgid "Trustor is disabled." +msgstr "" + +#: keystone/token/providers/uuid.py:238 +msgid "Trustee has no delegated roles." +msgstr "" + +#: keystone/token/providers/uuid.py:247 +#, python-format +msgid "User %(user_id)s has no access to project %(project_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:252 +#, python-format +msgid "User %(user_id)s has no access to domain %(domain_id)s" +msgstr "" + +#: keystone/token/providers/uuid.py:303 +msgid "User is not a trustee." +msgstr "" + +#: keystone/token/providers/uuid.py:457 +msgid "Non-default domain is not supported" +msgstr "ä¸æ”¯æ´éžé è¨ç¶²åŸŸ" + +#: keystone/token/providers/uuid.py:465 +msgid "Domain scoped token is not supported" +msgstr "ä¸æ”¯æ´ç¶²åŸŸç¯„åœçš„記號" + +#: keystone/token/providers/uuid.py:528 +msgid "Failed to validate token" +msgstr "" + +#: keystone/token/providers/uuid.py:566 keystone/token/providers/uuid.py:576 +msgid "Failed to verify token" +msgstr "" + +#~ msgid "User have no access to project" +#~ msgstr "使用者無法å˜å–專案" + +#~ msgid "User have no access to domain" +#~ msgstr "使用者無法å˜å–網域" + +#~ msgid "Invalid value for token_format: %s. Allowed values are PKI or UUID." +#~ msgstr "token_format 的值無效:%s。接å—的值為 PKI 或 UUID。" + diff --git a/keystone/openstack/common/crypto/__init__.py b/keystone/openstack/common/crypto/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/keystone/openstack/common/crypto/__init__.py diff --git a/keystone/openstack/common/crypto/utils.py b/keystone/openstack/common/crypto/utils.py new file mode 100644 index 00000000..ef178cab --- /dev/null +++ b/keystone/openstack/common/crypto/utils.py @@ -0,0 +1,179 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 Red Hat, Inc. +# +# 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 base64 + +from Crypto.Hash import HMAC +from Crypto import Random + +from keystone.openstack.common.gettextutils import _ +from keystone.openstack.common.importutils import import_module + + +class CryptoutilsException(Exception): + """Generic Exception for Crypto utilities.""" + + message = _("An unknown error occurred in crypto utils.") + + +class CipherBlockLengthTooBig(CryptoutilsException): + """The block size is too big.""" + + def __init__(self, requested, permitted): + msg = _("Block size of %(given)d is too big, max = %(maximum)d") + message = msg % {'given': requested, 'maximum': permitted} + super(CryptoutilsException, self).__init__(message) + + +class HKDFOutputLengthTooLong(CryptoutilsException): + """The amount of Key Material asked is too much.""" + + def __init__(self, requested, permitted): + msg = _("Length of %(given)d is too long, max = %(maximum)d") + message = msg % {'given': requested, 'maximum': permitted} + super(CryptoutilsException, self).__init__(message) + + +class HKDF(object): + """An HMAC-based Key Derivation Function implementation (RFC5869) + + This class creates an object that allows to use HKDF to derive keys. + """ + + def __init__(self, hashtype='SHA256'): + self.hashfn = import_module('Crypto.Hash.' + hashtype) + self.max_okm_length = 255 * self.hashfn.digest_size + + def extract(self, ikm, salt=None): + """An extract function that can be used to derive a robust key given + weak Input Key Material (IKM) which could be a password. + Returns a pseudorandom key (of HashLen octets) + + :param ikm: input keying material (ex a password) + :param salt: optional salt value (a non-secret random value) + """ + if salt is None: + salt = '\x00' * self.hashfn.digest_size + + return HMAC.new(salt, ikm, self.hashfn).digest() + + def expand(self, prk, info, length): + """An expand function that will return arbitrary length output that can + be used as keys. + Returns a buffer usable as key material. + + :param prk: a pseudorandom key of at least HashLen octets + :param info: optional string (can be a zero-length string) + :param length: length of output keying material (<= 255 * HashLen) + """ + if length > self.max_okm_length: + raise HKDFOutputLengthTooLong(length, self.max_okm_length) + + N = (length + self.hashfn.digest_size - 1) / self.hashfn.digest_size + + okm = "" + tmp = "" + for block in range(1, N + 1): + tmp = HMAC.new(prk, tmp + info + chr(block), self.hashfn).digest() + okm += tmp + + return okm[:length] + + +MAX_CB_SIZE = 256 + + +class SymmetricCrypto(object): + """Symmetric Key Crypto object. + + This class creates a Symmetric Key Crypto object that can be used + to encrypt, decrypt, or sign arbitrary data. + + :param enctype: Encryption Cipher name (default: AES) + :param hashtype: Hash/HMAC type name (default: SHA256) + """ + + def __init__(self, enctype='AES', hashtype='SHA256'): + self.cipher = import_module('Crypto.Cipher.' + enctype) + self.hashfn = import_module('Crypto.Hash.' + hashtype) + + def new_key(self, size): + return Random.new().read(size) + + def encrypt(self, key, msg, b64encode=True): + """Encrypt the provided msg and returns the cyphertext optionally + base64 encoded. + + Uses AES-128-CBC with a Random IV by default. + + The plaintext is padded to reach blocksize length. + The last byte of the block is the length of the padding. + The length of the padding does not include the length byte itself. + + :param key: The Encryption key. + :param msg: the plain text. + + :returns encblock: a block of encrypted data. + """ + iv = Random.new().read(self.cipher.block_size) + cipher = self.cipher.new(key, self.cipher.MODE_CBC, iv) + + # CBC mode requires a fixed block size. Append padding and length of + # padding. + if self.cipher.block_size > MAX_CB_SIZE: + raise CipherBlockLengthTooBig(self.cipher.block_size, MAX_CB_SIZE) + r = len(msg) % self.cipher.block_size + padlen = self.cipher.block_size - r - 1 + msg += '\x00' * padlen + msg += chr(padlen) + + enc = iv + cipher.encrypt(msg) + if b64encode: + enc = base64.b64encode(enc) + return enc + + def decrypt(self, key, msg, b64decode=True): + """Decrypts the provided ciphertext, optionally base 64 encoded, and + returns the plaintext message, after padding is removed. + + Uses AES-128-CBC with an IV by default. + + :param key: The Encryption key. + :param msg: the ciphetext, the first block is the IV + """ + if b64decode: + msg = base64.b64decode(msg) + iv = msg[:self.cipher.block_size] + cipher = self.cipher.new(key, self.cipher.MODE_CBC, iv) + + padded = cipher.decrypt(msg[self.cipher.block_size:]) + l = ord(padded[-1]) + 1 + plain = padded[:-l] + return plain + + def sign(self, key, msg, b64encode=True): + """Signs a message string and returns a base64 encoded signature. + + Uses HMAC-SHA-256 by default. + + :param key: The Signing key. + :param msg: the message to sign. + """ + h = HMAC.new(key, msg, self.hashfn) + out = h.digest() + if b64encode: + out = base64.b64encode(out) + return out diff --git a/keystone/service.py b/keystone/service.py index 406004d6..ce64aba8 100644 --- a/keystone/service.py +++ b/keystone/service.py @@ -16,8 +16,10 @@ import routes +from keystone import assignment from keystone import auth from keystone import catalog +from keystone.common import dependency from keystone.common import logging from keystone.common import wsgi from keystone import config @@ -34,14 +36,24 @@ from keystone import trust CONF = config.CONF LOG = logging.getLogger(__name__) + +# Ensure that the identity driver is created before the assignment manager. +# The default assignment driver is determined by the identity driver, so the +# identity driver must be available to the assignment manager. +_IDENTITY_API = identity.Manager() + DRIVERS = dict( + assignment_api=assignment.Manager(), catalog_api=catalog.Manager(), credentials_api=credential.Manager(), ec2_api=ec2.Manager(), - identity_api=identity.Manager(), + identity_api=_IDENTITY_API, policy_api=policy.Manager(), token_api=token.Manager(), - trust_api=trust.Manager()) + trust_api=trust.Manager(), + token_provider_api=token.provider.Manager()) + +dependency.resolve_future_dependencies() @logging.fail_gracefully diff --git a/keystone/test.py b/keystone/test.py index e68676ca..9118b2ea 100644 --- a/keystone/test.py +++ b/keystone/test.py @@ -17,6 +17,7 @@ import datetime import errno import os +import shutil import socket import StringIO import sys @@ -35,18 +36,23 @@ gettext.install('keystone', unicode=1) from keystone.common import environment environment.use_eventlet() +from keystone import assignment from keystone import catalog +from keystone.common import dependency from keystone.common import kvs from keystone.common import logging +from keystone.common import sql from keystone.common import utils from keystone.common import wsgi from keystone import config +from keystone.contrib import ec2 from keystone import credential from keystone import exception from keystone import identity from keystone.openstack.common import timeutils from keystone import policy from keystone import token +from keystone.token import provider as token_provider from keystone import trust @@ -55,6 +61,8 @@ ROOTDIR = os.path.dirname(os.path.abspath(os.curdir)) VENDOR = os.path.join(ROOTDIR, 'vendor') TESTSDIR = os.path.join(ROOTDIR, 'tests') ETCDIR = os.path.join(ROOTDIR, 'etc') +TMPDIR = os.path.join(TESTSDIR, 'tmp') + CONF = config.CONF cd = os.chdir @@ -75,6 +83,10 @@ def testsdir(*p): return os.path.join(TESTSDIR, *p) +def tmpdir(*p): + return os.path.join(TMPDIR, *p) + + def checkout_vendor(repo, rev): # TODO(termie): this function is a good target for some optimizations :PERF name = repo.split('/')[-1] @@ -107,6 +119,26 @@ def checkout_vendor(repo, rev): return revdir +def setup_test_database(): + db = tmpdir('test.db') + pristine = tmpdir('test.db.pristine') + + try: + if os.path.exists(db): + os.unlink(db) + if not os.path.exists(pristine): + sql.migration.db_sync() + shutil.copyfile(db, pristine) + else: + shutil.copyfile(pristine, db) + except Exception: + pass + + +def teardown_test_database(): + sql.core.set_global_engine(None) + + class TestClient(object): def __init__(self, app=None, token=None): self.app = app @@ -210,6 +242,11 @@ class TestCase(NoModule, unittest.TestCase): for path in self._paths: if path in sys.path: sys.path.remove(path) + + # Clear the registry of providers so that providers from previous + # tests aren't used. + dependency.reset() + kvs.INMEMDB.clear() CONF.reset() @@ -223,10 +260,28 @@ class TestCase(NoModule, unittest.TestCase): def load_backends(self): """Initializes each manager and assigns them to an attribute.""" - for manager in [catalog, credential, identity, policy, token, trust]: - manager_name = '%s_api' % manager.__name__.split('.')[-1] + + # TODO(blk-u): Shouldn't need to clear the registry here, but some + # tests call load_backends multiple times. These should be fixed to + # only call load_backends once. + dependency.reset() + + # NOTE(blk-u): identity must be before assignment to ensure that the + # identity driver is available to the assignment manager because the + # assignment manager gets the default assignment driver from the + # identity driver. + for manager in [identity, assignment, catalog, credential, ec2, policy, + token, token_provider, trust]: + # manager.__name__ is like keystone.xxx[.yyy], + # converted to xxx[_yyy] + manager_name = ('%s_api' % + manager.__name__.replace('keystone.', ''). + replace('.', '_')) + setattr(self, manager_name, manager.Manager()) + dependency.resolve_future_dependencies() + def load_fixtures(self, fixtures): """Hacky basic and naive fixture loading based on a python module. @@ -276,19 +331,6 @@ class TestCase(NoModule, unittest.TestCase): pass setattr(self, 'user_%s' % user['id'], user_copy) - for metadata in fixtures.METADATA: - metadata_ref = metadata.copy() - # TODO(termie): these will probably end up in the model anyway, - # so this may be futile - del metadata_ref['user_id'] - del metadata_ref['tenant_id'] - rv = self.identity_api.create_metadata(metadata['user_id'], - metadata['tenant_id'], - metadata_ref) - setattr(self, - 'metadata_%s%s' % (metadata['user_id'], - metadata['tenant_id']), rv) - def _paste_config(self, config): if not config.startswith('config:'): test_path = os.path.join(TESTSDIR, config) diff --git a/keystone/token/__init__.py b/keystone/token/__init__.py index 889cd39a..ffd9bc44 100644 --- a/keystone/token/__init__.py +++ b/keystone/token/__init__.py @@ -17,4 +17,5 @@ from keystone.token import controllers from keystone.token.core import * +from keystone.token import provider from keystone.token import routers diff --git a/keystone/token/backends/kvs.py b/keystone/token/backends/kvs.py index c16dd61b..c3c3e769 100644 --- a/keystone/token/backends/kvs.py +++ b/keystone/token/backends/kvs.py @@ -17,16 +17,29 @@ import copy from keystone.common import kvs +from keystone.common import logging from keystone import exception from keystone.openstack.common import timeutils from keystone import token +LOG = logging.getLogger(__name__) + class Token(kvs.Base, token.Driver): + """kvs backend for tokens is deprecated. + + Deprecated in Havana and will be removed in Icehouse, as this backend + is not production grade. + """ + + def __init__(self, *args, **kw): + super(Token, self).__init__(*args, **kw) + LOG.warn(_("kvs token backend is DEPRECATED. Use " + "keystone.token.backends.sql or " + "keystone.token.backend.memcache instead.")) # Public interface def get_token(self, token_id): - token_id = token.unique_id(token_id) try: ref = self.db.get('token-%s' % token_id) except exception.NotFound: @@ -41,7 +54,6 @@ class Token(kvs.Base, token.Driver): raise exception.TokenNotFound(token_id=token_id) def create_token(self, token_id, data): - token_id = token.unique_id(token_id) data_copy = copy.deepcopy(data) data_copy['id'] = token_id if not data_copy.get('expires'): @@ -52,7 +64,6 @@ class Token(kvs.Base, token.Driver): return copy.deepcopy(data_copy) def delete_token(self, token_id): - token_id = token.unique_id(token_id) try: token_ref = self.get_token(token_id) self.db.delete('token-%s' % token_id) diff --git a/keystone/token/backends/memcache.py b/keystone/token/backends/memcache.py index e9d8482f..06e89d60 100644 --- a/keystone/token/backends/memcache.py +++ b/keystone/token/backends/memcache.py @@ -65,7 +65,7 @@ class Token(token.Driver): def get_token(self, token_id): if token_id is None: raise exception.TokenNotFound(token_id='') - ptk = self._prefix_token_id(token.unique_id(token_id)) + ptk = self._prefix_token_id(token_id) token_ref = self.client.get(ptk) if token_ref is None: raise exception.TokenNotFound(token_id=token_id) @@ -74,7 +74,7 @@ class Token(token.Driver): def create_token(self, token_id, data): data_copy = copy.deepcopy(data) - ptk = self._prefix_token_id(token.unique_id(token_id)) + ptk = self._prefix_token_id(token_id) if not data_copy.get('expires'): data_copy['expires'] = token.default_expire_time() if not data_copy.get('user_id'): @@ -118,7 +118,7 @@ class Token(token.Driver): if record is not None: token_list = jsonutils.loads('[%s]' % record) for token_i in token_list: - ptk = self._prefix_token_id(token.unique_id(token_i)) + ptk = self._prefix_token_id(token_i) token_ref = self.client.get(ptk) if not token_ref: # skip tokens that do not exist in memcache @@ -174,8 +174,8 @@ class Token(token.Driver): def delete_token(self, token_id): # Test for existence - data = self.get_token(token.unique_id(token_id)) - ptk = self._prefix_token_id(token.unique_id(token_id)) + data = self.get_token(token_id) + ptk = self._prefix_token_id(token_id) result = self.client.delete(ptk) self._add_to_revocation_list(data) return result @@ -186,7 +186,7 @@ class Token(token.Driver): user_record = self.client.get(user_key) or "" token_list = jsonutils.loads('[%s]' % user_record) for token_id in token_list: - ptk = self._prefix_token_id(token.unique_id(token_id)) + ptk = self._prefix_token_id(token_id) token_ref = self.client.get(ptk) if token_ref: if tenant_id is not None: diff --git a/keystone/token/backends/sql.py b/keystone/token/backends/sql.py index 57dbf410..0e8a916d 100644 --- a/keystone/token/backends/sql.py +++ b/keystone/token/backends/sql.py @@ -41,7 +41,7 @@ class Token(sql.Base, token.Driver): if token_id is None: raise exception.TokenNotFound(token_id=token_id) session = self.get_session() - token_ref = session.query(TokenModel).get(token.unique_id(token_id)) + token_ref = session.query(TokenModel).get(token_id) now = datetime.datetime.utcnow() if not token_ref or not token_ref.valid: raise exception.TokenNotFound(token_id=token_id) @@ -59,7 +59,6 @@ class Token(sql.Base, token.Driver): data_copy['user_id'] = data_copy['user']['id'] token_ref = TokenModel.from_dict(data_copy) - token_ref.id = token.unique_id(token_id) token_ref.valid = True session = self.get_session() with session.begin(): @@ -69,9 +68,8 @@ class Token(sql.Base, token.Driver): def delete_token(self, token_id): session = self.get_session() - key = token.unique_id(token_id) with session.begin(): - token_ref = session.query(TokenModel).get(key) + token_ref = session.query(TokenModel).get(token_id) if not token_ref or not token_ref.valid: raise exception.TokenNotFound(token_id=token_id) token_ref.valid = False diff --git a/keystone/token/controllers.py b/keystone/token/controllers.py index 34700106..9ebc29fe 100644 --- a/keystone/token/controllers.py +++ b/keystone/token/controllers.py @@ -1,17 +1,17 @@ import json -import sys -import uuid from keystone.common import cms from keystone.common import controller from keystone.common import dependency -from keystone.common import environment from keystone.common import logging from keystone.common import utils +from keystone.common import wsgi from keystone import config from keystone import exception from keystone.openstack.common import timeutils from keystone.token import core +from keystone.token import provider as token_provider + CONF = config.CONF LOG = logging.getLogger(__name__) @@ -23,7 +23,7 @@ class ExternalAuthNotApplicable(Exception): pass -@dependency.requires('catalog_api', 'trust_api', 'token_api') +@dependency.requires('token_provider_api') class Auth(controller.V2Controller): def ca_cert(self, context, auth=None): ca_file = open(CONF.signing.ca_certs, 'r') @@ -79,9 +79,8 @@ class Auth(controller.V2Controller): auth_info = self._authenticate_local( context, auth) - user_ref, tenant_ref, metadata_ref, expiry = auth_info + user_ref, tenant_ref, metadata_ref, expiry, bind = auth_info core.validate_auth_info(self, user_ref, tenant_ref) - trust_id = metadata_ref.get('trust_id') user_ref = self._filter_domain_id(user_ref) if tenant_ref: tenant_ref = self._filter_domain_id(tenant_ref) @@ -92,59 +91,24 @@ class Auth(controller.V2Controller): if tenant_ref: catalog_ref = self.catalog_api.get_catalog( - user_id=user_ref['id'], - tenant_id=tenant_ref['id'], - metadata=metadata_ref) + user_ref['id'], tenant_ref['id'], metadata_ref) else: catalog_ref = {} auth_token_data['id'] = 'placeholder' + if bind: + auth_token_data['bind'] = bind roles_ref = [] for role_id in metadata_ref.get('roles', []): role_ref = self.identity_api.get_role(role_id) roles_ref.append(dict(name=role_ref['name'])) - token_data = Auth.format_token(auth_token_data, roles_ref) - - service_catalog = Auth.format_catalog(catalog_ref) - token_data['access']['serviceCatalog'] = service_catalog - - if CONF.signing.token_format == 'UUID': - token_id = uuid.uuid4().hex - elif CONF.signing.token_format == 'PKI': - try: - token_id = cms.cms_sign_token(json.dumps(token_data), - CONF.signing.certfile, - CONF.signing.keyfile) - except environment.subprocess.CalledProcessError: - raise exception.UnexpectedError(_( - 'Unable to sign token.')) - else: - raise exception.UnexpectedError(_( - 'Invalid value for token_format: %s.' - ' Allowed values are PKI or UUID.') % - CONF.signing.token_format) - try: - self.token_api.create_token( - token_id, dict(key=token_id, - id=token_id, - expires=auth_token_data['expires'], - user=user_ref, - tenant=tenant_ref, - metadata=metadata_ref, - trust_id=trust_id)) - except Exception: - exc_info = sys.exc_info() - # an identical token may have been created already. - # if so, return the token_data as it is also identical - try: - self.token_api.get_token(token_id) - except exception.TokenNotFound: - raise exc_info[0], exc_info[1], exc_info[2] - - token_data['access']['token']['id'] = token_id - + (token_id, token_data) = self.token_provider_api.issue_token( + version=token_provider.V2, + token_ref=auth_token_data, + roles_ref=roles_ref, + catalog_ref=catalog_ref) return token_data def _authenticate_token(self, context, auth): @@ -170,6 +134,8 @@ class Auth(controller.V2Controller): except exception.NotFound as e: raise exception.Unauthorized(e) + wsgi.validate_token_bind(context, old_token_ref) + #A trust token cannot be used to get another token if 'trust' in old_token_ref: raise exception.Forbidden() @@ -207,17 +173,10 @@ class Auth(controller.V2Controller): else: current_user_ref = self.identity_api.get_user(user_id) + metadata_ref = {} tenant_id = self._get_project_id_from_auth(auth) - - tenant_ref = self._get_project_ref(user_id, tenant_id) - metadata_ref = self._get_metadata_ref(user_id, tenant_id) - - # TODO(henry-nash): If no tenant was specified, instead check for a - # domain and find any related user/group roles - - self._append_roles(metadata_ref, - self._get_group_metadata_ref( - context, user_id, tenant_id)) + tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( + user_id, tenant_id) expiry = old_token_ref['expires'] if CONF.trust.enabled and 'trust_id' in auth: @@ -238,7 +197,9 @@ class Auth(controller.V2Controller): metadata_ref['trustee_user_id'] = trust_ref['trustee_user_id'] metadata_ref['trust_id'] = trust_id - return (current_user_ref, tenant_ref, metadata_ref, expiry) + bind = old_token_ref.get('bind', None) + + return (current_user_ref, tenant_ref, metadata_ref, expiry, bind) def _authenticate_local(self, context, auth): """Try to authenticate against the identity backend. @@ -283,30 +244,20 @@ class Auth(controller.V2Controller): except exception.UserNotFound as e: raise exception.Unauthorized(e) - tenant_id = self._get_project_id_from_auth(auth) - try: - auth_info = self.identity_api.authenticate( + user_ref = self.identity_api.authenticate( user_id=user_id, - password=password, - tenant_id=tenant_id) + password=password) except AssertionError as e: raise exception.Unauthorized(e) - (user_ref, tenant_ref, metadata_ref) = auth_info - # By now we will have authorized and if a tenant/project was - # specified, we will have obtained its metadata. In this case - # we just need to add in any group roles. - # - # TODO(henry-nash): If no tenant was specified, instead check for a - # domain and find any related user/group roles - - self._append_roles(metadata_ref, - self._get_group_metadata_ref( - context, user_id, tenant_id)) + metadata_ref = {} + tenant_id = self._get_project_id_from_auth(auth) + tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( + user_id, tenant_id) expiry = core.default_expire_time() - return (user_ref, tenant_ref, metadata_ref, expiry) + return (user_ref, tenant_ref, metadata_ref, expiry, None) def _authenticate_external(self, context, auth): """Try to authenticate an external user via REMOTE_USER variable. @@ -316,6 +267,11 @@ class Auth(controller.V2Controller): if 'REMOTE_USER' not in context: raise ExternalAuthNotApplicable() + #NOTE(jamielennox): xml and json differ and get confused about what + # empty auth should look like so just reset it. + if not auth: + auth = {} + username = context['REMOTE_USER'] try: user_ref = self.identity_api.get_user_by_name( @@ -324,20 +280,18 @@ class Auth(controller.V2Controller): except exception.UserNotFound as e: raise exception.Unauthorized(e) + metadata_ref = {} tenant_id = self._get_project_id_from_auth(auth) - - tenant_ref = self._get_project_ref(user_id, tenant_id) - metadata_ref = self._get_metadata_ref(user_id, tenant_id) - - # TODO(henry-nash): If no tenant was specified, instead check for a - # domain and find any related user/group roles - - self._append_roles(metadata_ref, - self._get_group_metadata_ref( - context, user_id, tenant_id)) + tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( + user_id, tenant_id) expiry = core.default_expire_time() - return (user_ref, tenant_ref, metadata_ref, expiry) + bind = None + if ('kerberos' in CONF.token.bind and + context.get('AUTH_TYPE', '').lower() == 'negotiate'): + bind = {'kerberos': username} + + return (user_ref, tenant_ref, metadata_ref, expiry, bind) def _get_auth_token_data(self, user, tenant, metadata, expiry): return dict(user=user, @@ -405,40 +359,26 @@ class Auth(controller.V2Controller): exception.Unauthorized(e) return tenant_ref - def _get_metadata_ref(self, user_id=None, tenant_id=None, domain_id=None, - group_id=None): - """Returns metadata_ref for a user or group in a tenant or domain.""" + def _get_project_roles_and_ref(self, user_id, tenant_id): + """Returns the project roles for this user, and the project ref.""" - metadata_ref = {} - if (user_id or group_id) and (tenant_id or domain_id): + tenant_ref = None + role_list = [] + if tenant_id: try: - metadata_ref = self.identity_api.get_metadata( - user_id=user_id, tenant_id=tenant_id, - domain_id=domain_id, group_id=group_id) - except exception.MetadataNotFound: + tenant_ref = self.identity_api.get_project(tenant_id) + role_list = self.identity_api.get_roles_for_user_and_project( + user_id, tenant_id) + except exception.ProjectNotFound: pass - return metadata_ref - - def _get_group_metadata_ref(self, context, user_id, - tenant_id=None, domain_id=None): - """Return any metadata for this project/domain due to group grants.""" - group_refs = self.identity_api.list_groups_for_user(user_id) - metadata_ref = {} - for x in group_refs: - metadata_ref.update(self._get_metadata_ref( - group_id=x['id'], tenant_id=tenant_id, domain_id=domain_id)) - return metadata_ref - def _append_roles(self, metadata, additional_metadata): - """Add additional roles to the roles in metadata. - - The final set of roles represents the union of existing roles and - additional roles. - """ + if not role_list: + msg = _('User %(u_id)s is unauthorized for tenant %(t_id)s') + msg = msg % {'u_id': user_id, 't_id': tenant_id} + LOG.warning(msg) + raise exception.Unauthorized(msg) - first = set(metadata.get('roles', [])) - second = set(additional_metadata.get('roles', [])) - metadata['roles'] = list(first.union(second)) + return (tenant_ref, role_list) def _get_token_ref(self, token_id, belongs_to=None): """Returns a token if a valid one exists. @@ -456,45 +396,6 @@ class Auth(controller.V2Controller): _('Token does not belong to specified tenant.')) return data - def _assert_default_domain(self, token_ref): - """Make sure we are operating on default domain only.""" - if token_ref.get('token_data'): - # this is a V3 token - msg = _('Non-default domain is not supported') - # user in a non-default is prohibited - if (token_ref['token_data']['token']['user']['domain']['id'] != - DEFAULT_DOMAIN_ID): - raise exception.Unauthorized(msg) - # domain scoping is prohibited - if token_ref['token_data']['token'].get('domain'): - raise exception.Unauthorized( - _('Domain scoped token is not supported')) - # project in non-default domain is prohibited - if token_ref['token_data']['token'].get('project'): - project = token_ref['token_data']['token']['project'] - project_domain_id = project['domain']['id'] - # scoped to project in non-default domain is prohibited - if project_domain_id != DEFAULT_DOMAIN_ID: - raise exception.Unauthorized(msg) - # if token is scoped to trust, both trustor and trustee must - # be in the default domain. Furthermore, the delegated project - # must also be in the default domain - metadata_ref = token_ref['metadata'] - if CONF.trust.enabled and 'trust_id' in metadata_ref: - trust_ref = self.trust_api.get_trust(metadata_ref['trust_id']) - trustee_user_ref = self.identity_api.get_user( - trust_ref['trustee_user_id']) - if trustee_user_ref['domain_id'] != DEFAULT_DOMAIN_ID: - raise exception.Unauthorized(msg) - trustor_user_ref = self.identity_api.get_user( - trust_ref['trustor_user_id']) - if trustor_user_ref['domain_id'] != DEFAULT_DOMAIN_ID: - raise exception.Unauthorized(msg) - project_ref = self.identity_api.get_project( - trust_ref['project_id']) - if project_ref['domain_id'] != DEFAULT_DOMAIN_ID: - raise exception.Unauthorized(msg) - @controller.protected def validate_token_head(self, context, token_id): """Check that a token is valid. @@ -505,9 +406,9 @@ class Auth(controller.V2Controller): """ belongs_to = context['query_string'].get('belongsTo') - token_ref = self._get_token_ref(token_id, belongs_to) - assert token_ref - self._assert_default_domain(token_ref) + self.token_provider_api.check_token(token_id, + belongs_to=belongs_to, + version=token_provider.V2) @controller.protected def validate_token(self, context, token_id): @@ -519,26 +420,9 @@ class Auth(controller.V2Controller): """ belongs_to = context['query_string'].get('belongsTo') - token_ref = self._get_token_ref(token_id, belongs_to) - self._assert_default_domain(token_ref) - - # TODO(termie): optimize this call at some point and put it into the - # the return for metadata - # fill out the roles in the metadata - metadata_ref = token_ref['metadata'] - roles_ref = [] - for role_id in metadata_ref.get('roles', []): - roles_ref.append(self.identity_api.get_role(role_id)) - - # Get a service catalog if possible - # This is needed for on-behalf-of requests - catalog_ref = None - if token_ref.get('tenant'): - catalog_ref = self.catalog_api.get_catalog( - user_id=token_ref['user']['id'], - tenant_id=token_ref['tenant']['id'], - metadata=metadata_ref) - return Auth.format_token(token_ref, roles_ref, catalog_ref) + return self.token_provider_api.validate_token( + token_id, belongs_to=belongs_to, + version=token_provider.V2) def delete_token(self, context, token_id): """Delete a token, effectively invalidating it for authz.""" @@ -571,106 +455,13 @@ class Auth(controller.V2Controller): catalog_ref = None if token_ref.get('tenant'): catalog_ref = self.catalog_api.get_catalog( - user_id=token_ref['user']['id'], - tenant_id=token_ref['tenant']['id'], - metadata=token_ref['metadata']) + token_ref['user']['id'], + token_ref['tenant']['id'], + token_ref['metadata']) return Auth.format_endpoint_list(catalog_ref) @classmethod - def format_authenticate(cls, token_ref, roles_ref, catalog_ref): - o = Auth.format_token(token_ref, roles_ref) - o['access']['serviceCatalog'] = Auth.format_catalog(catalog_ref) - return o - - @classmethod - def format_token(cls, token_ref, roles_ref, catalog_ref=None): - user_ref = token_ref['user'] - metadata_ref = token_ref['metadata'] - expires = token_ref['expires'] - if expires is not None: - if not isinstance(expires, unicode): - expires = timeutils.isotime(expires) - o = {'access': {'token': {'id': token_ref['id'], - 'expires': expires, - 'issued_at': timeutils.strtime() - }, - 'user': {'id': user_ref['id'], - 'name': user_ref['name'], - 'username': user_ref['name'], - 'roles': roles_ref, - 'roles_links': metadata_ref.get('roles_links', - []) - } - } - } - if 'tenant' in token_ref and token_ref['tenant']: - token_ref['tenant']['enabled'] = True - o['access']['token']['tenant'] = token_ref['tenant'] - if catalog_ref is not None: - o['access']['serviceCatalog'] = Auth.format_catalog(catalog_ref) - if metadata_ref: - if 'is_admin' in metadata_ref: - o['access']['metadata'] = {'is_admin': - metadata_ref['is_admin']} - else: - o['access']['metadata'] = {'is_admin': 0} - if 'roles' in metadata_ref: - o['access']['metadata']['roles'] = metadata_ref['roles'] - if CONF.trust.enabled and 'trust_id' in metadata_ref: - o['access']['trust'] = {'trustee_user_id': - metadata_ref['trustee_user_id'], - 'id': metadata_ref['trust_id'] - } - return o - - @classmethod - def format_catalog(cls, catalog_ref): - """Munge catalogs from internal to output format - Internal catalogs look like: - - {$REGION: { - {$SERVICE: { - $key1: $value1, - ... - } - } - } - - The legacy api wants them to look like - - [{'name': $SERVICE[name], - 'type': $SERVICE, - 'endpoints': [{ - 'tenantId': $tenant_id, - ... - 'region': $REGION, - }], - 'endpoints_links': [], - }] - - """ - if not catalog_ref: - return [] - - services = {} - for region, region_ref in catalog_ref.iteritems(): - for service, service_ref in region_ref.iteritems(): - new_service_ref = services.get(service, {}) - new_service_ref['name'] = service_ref.pop('name') - new_service_ref['type'] = service - new_service_ref['endpoints_links'] = [] - service_ref['region'] = region - - endpoints_ref = new_service_ref.get('endpoints', []) - endpoints_ref.append(service_ref) - - new_service_ref['endpoints'] = endpoints_ref - services[service] = new_service_ref - - return services.values() - - @classmethod def format_endpoint_list(cls, catalog_ref): """Formats a list of endpoints according to Identity API v2. diff --git a/keystone/token/core.py b/keystone/token/core.py index a8a3b82d..bc27b80d 100644 --- a/keystone/token/core.py +++ b/keystone/token/core.py @@ -16,6 +16,7 @@ """Main entry point into the Token service.""" +import copy import datetime from keystone.common import cms @@ -32,19 +33,6 @@ config.register_int('expiration', group='token', default=86400) LOG = logging.getLogger(__name__) -def unique_id(token_id): - """Return a unique ID for a token. - - The returned value is useful as the primary key of a database table, - memcache store, or other lookup table. - - :returns: Given a PKI token, returns it's hashed value. Otherwise, returns - the passed-in value (such as a UUID token ID or an existing - hash). - """ - return cms.cms_hash_token(token_id) - - def default_expire_time(): """Determine when a fresh token should expire. @@ -114,6 +102,29 @@ class Manager(manager.Manager): def __init__(self): super(Manager, self).__init__(CONF.token.driver) + def _unique_id(self, token_id): + """Return a unique ID for a token. + + The returned value is useful as the primary key of a database table, + memcache store, or other lookup table. + + :returns: Given a PKI token, returns it's hashed value. Otherwise, + returns the passed-in value (such as a UUID token ID or an + existing hash). + """ + return cms.cms_hash_token(token_id) + + def get_token(self, token_id): + return self.driver.get_token(self._unique_id(token_id)) + + def create_token(self, token_id, data): + data_copy = copy.deepcopy(data) + data_copy['id'] = self._unique_id(token_id) + return self.driver.create_token(self._unique_id(token_id), data_copy) + + def delete_token(self, token_id): + return self.driver.delete_token(self._unique_id(token_id)) + class Driver(object): """Interface description for a Token driver.""" diff --git a/keystone/token/provider.py b/keystone/token/provider.py new file mode 100644 index 00000000..2864be6f --- /dev/null +++ b/keystone/token/provider.py @@ -0,0 +1,177 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2012 OpenStack LLC +# +# 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. + +"""Token provider interface.""" + + +from keystone.common import dependency +from keystone.common import logging +from keystone.common import manager +from keystone import config +from keystone import exception + + +CONF = config.CONF +LOG = logging.getLogger(__name__) + + +# supported token versions +V2 = 'v2.0' +V3 = 'v3.0' + +# default token providers +PKI_PROVIDER = 'keystone.token.providers.pki.Provider' +UUID_PROVIDER = 'keystone.token.providers.uuid.Provider' + + +class UnsupportedTokenVersionException(Exception): + """Token version is unrecognizable or unsupported.""" + pass + + +@dependency.provider('token_provider_api') +class Manager(manager.Manager): + """Default pivot point for the token provider backend. + + See :mod:`keystone.common.manager.Manager` for more details on how this + dynamically calls the backend. + + """ + + @classmethod + def get_token_provider(cls): + """Return package path to the configured token provider. + + The value should come from ``keystone.conf`` ``[token] provider``, + however this method ensures backwards compatibility for + ``keystone.conf`` ``[signing] token_format`` until Havana + 2. + + Return the provider based on ``token_format`` if ``provider`` is not + set. Otherwise, ignore ``token_format`` and return the configured + ``provider`` instead. + + """ + if CONF.token.provider is not None: + # NOTE(gyee): we are deprecating CONF.signing.token_format. This + # code is to ensure the token provider configuration agrees with + # CONF.signing.token_format. + if ((CONF.signing.token_format == 'PKI' and + CONF.token.provider != PKI_PROVIDER or + (CONF.signing.token_format == 'UUID' and + CONF.token.provider != UUID_PROVIDER))): + raise exception.UnexpectedError( + _('keystone.conf [signing] token_format (deprecated) ' + 'conflicts with keystone.conf [token] provider')) + return CONF.token.provider + else: + if not CONF.signing.token_format: + # No token provider and no format, so use default (PKI) + return PKI_PROVIDER + + msg = _('keystone.conf [signing] token_format is deprecated in ' + 'favor of keystone.conf [token] provider') + if CONF.signing.token_format == 'PKI': + LOG.warning(msg) + return PKI_PROVIDER + elif CONF.signing.token_format == 'UUID': + LOG.warning(msg) + return UUID_PROVIDER + else: + raise exception.UnexpectedError( + _('Unrecognized keystone.conf [signing] token_format: ' + 'expected either \'UUID\' or \'PKI\'')) + + def __init__(self): + super(Manager, self).__init__(self.get_token_provider()) + + +class Provider(object): + """Interface description for a Token provider.""" + + def get_token_version(self, token_data): + """Return the version of the given token data. + + If the given token data is unrecognizable, + UnsupportedTokenVersionException is raised. + + """ + raise exception.NotImplemented() + + def issue_token(self, version='v3.0', **kwargs): + """Issue a V3 token. + + For V3 tokens, 'user_id', 'method_names', must present in kwargs. + Optionally, kwargs may contain 'expires_at' for rescope tokens; + 'project_id' for project-scoped token; 'domain_id' for + domain-scoped token; and 'auth_context' from the authentication + plugins. + + For V2 tokens, 'token_ref' must be present in kwargs. + Optionally, kwargs may contain 'roles_ref' and 'catalog_ref'. + + :param context: request context + :type context: dictionary + :param version: version of the token to be issued + :type version: string + :param kwargs: information needed for token creation. Parameters + may be different depending on token version. + :type kwargs: dictionary + :returns: (token_id, token_data) + + """ + raise exception.NotImplemented() + + def revoke_token(self, token_id): + """Revoke a given token. + + :param token_id: identity of the token + :type token_id: string + :returns: None. + """ + raise exception.NotImplemented() + + def validate_token(self, token_id, belongs_to=None, version='v3.0'): + """Validate the given token and return the token data. + + Must raise Unauthorized exception if unable to validate token. + + :param token_id: identity of the token + :type token_id: string + :param belongs_to: identity of the scoped project to validate + :type belongs_to: string + :param version: version of the token to be validated + :type version: string + :returns: token data + :raises: keystone.exception.Unauthorized + + """ + raise exception.NotImplemented() + + def check_token(self, token_id, belongs_to=None, version='v3.0'): + """Check the validity of the given V3 token. + + Must raise Unauthorized exception if unable to check token. + + :param token_id: identity of the token + :type token_id: string + :param belongs_to: identity of the scoped project to validate + :type belongs_to: string + :param version: version of the token to check + :type version: string + :returns: None + :raises: keystone.exception.Unauthorized + + """ diff --git a/keystone/token/providers/__init__.py b/keystone/token/providers/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/keystone/token/providers/__init__.py diff --git a/keystone/token/providers/pki.py b/keystone/token/providers/pki.py new file mode 100644 index 00000000..81abe5d4 --- /dev/null +++ b/keystone/token/providers/pki.py @@ -0,0 +1,44 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 OpenStack LLC +# +# 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. + +"""Keystone PKI Token Provider""" + +import json + +from keystone.common import cms +from keystone.common import environment +from keystone.common import logging +from keystone import config +from keystone import exception +from keystone.token.providers import uuid + + +CONF = config.CONF + +LOG = logging.getLogger(__name__) + + +class Provider(uuid.Provider): + def _get_token_id(self, token_data): + try: + token_id = cms.cms_sign_token(json.dumps(token_data), + CONF.signing.certfile, + CONF.signing.keyfile) + return token_id + except environment.subprocess.CalledProcessError: + LOG.exception('Unable to sign token') + raise exception.UnexpectedError(_( + 'Unable to sign token.')) diff --git a/keystone/token/providers/uuid.py b/keystone/token/providers/uuid.py new file mode 100644 index 00000000..acfa9372 --- /dev/null +++ b/keystone/token/providers/uuid.py @@ -0,0 +1,577 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 OpenStack LLC +# +# 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. + +"""Keystone UUID Token Provider""" + +from __future__ import absolute_import + +import sys +import uuid + +from keystone.common import dependency +from keystone.common import logging +from keystone import config +from keystone import exception +from keystone.openstack.common import timeutils +from keystone import token +from keystone import trust + + +LOG = logging.getLogger(__name__) +CONF = config.CONF +DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id + + +@dependency.requires('catalog_api', 'identity_api') +class V2TokenDataHelper(object): + """Creates V2 token data.""" + @classmethod + def format_token(cls, token_ref, roles_ref, catalog_ref=None): + user_ref = token_ref['user'] + metadata_ref = token_ref['metadata'] + expires = token_ref.get('expires', token.default_expire_time()) + if expires is not None: + if not isinstance(expires, unicode): + expires = timeutils.isotime(expires) + o = {'access': {'token': {'id': token_ref['id'], + 'expires': expires, + 'issued_at': timeutils.strtime() + }, + 'user': {'id': user_ref['id'], + 'name': user_ref['name'], + 'username': user_ref['name'], + 'roles': roles_ref, + 'roles_links': metadata_ref.get('roles_links', + []) + } + } + } + if 'bind' in token_ref: + o['access']['token']['bind'] = token_ref['bind'] + if 'tenant' in token_ref and token_ref['tenant']: + token_ref['tenant']['enabled'] = True + o['access']['token']['tenant'] = token_ref['tenant'] + if catalog_ref is not None: + o['access']['serviceCatalog'] = V2TokenDataHelper.format_catalog( + catalog_ref) + if metadata_ref: + if 'is_admin' in metadata_ref: + o['access']['metadata'] = {'is_admin': + metadata_ref['is_admin']} + else: + o['access']['metadata'] = {'is_admin': 0} + if 'roles' in metadata_ref: + o['access']['metadata']['roles'] = metadata_ref['roles'] + if CONF.trust.enabled and 'trust_id' in metadata_ref: + o['access']['trust'] = {'trustee_user_id': + metadata_ref['trustee_user_id'], + 'id': metadata_ref['trust_id'] + } + return o + + @classmethod + def format_catalog(cls, catalog_ref): + """Munge catalogs from internal to output format + Internal catalogs look like: + + {$REGION: { + {$SERVICE: { + $key1: $value1, + ... + } + } + } + + The legacy api wants them to look like + + [{'name': $SERVICE[name], + 'type': $SERVICE, + 'endpoints': [{ + 'tenantId': $tenant_id, + ... + 'region': $REGION, + }], + 'endpoints_links': [], + }] + + """ + if not catalog_ref: + return [] + + services = {} + for region, region_ref in catalog_ref.iteritems(): + for service, service_ref in region_ref.iteritems(): + new_service_ref = services.get(service, {}) + new_service_ref['name'] = service_ref.pop('name') + new_service_ref['type'] = service + new_service_ref['endpoints_links'] = [] + service_ref['region'] = region + + endpoints_ref = new_service_ref.get('endpoints', []) + endpoints_ref.append(service_ref) + + new_service_ref['endpoints'] = endpoints_ref + services[service] = new_service_ref + + return services.values() + + @classmethod + def get_token_data(cls, **kwargs): + if 'token_ref' not in kwargs: + raise ValueError('Require token_ref to create V2 token data') + token_ref = kwargs.get('token_ref') + roles_ref = kwargs.get('roles_ref', []) + catalog_ref = kwargs.get('catalog_ref') + return V2TokenDataHelper.format_token( + token_ref, roles_ref, catalog_ref) + + +@dependency.requires('catalog_api', 'identity_api') +class V3TokenDataHelper(object): + """Token data helper.""" + def __init__(self): + if CONF.trust.enabled: + self.trust_api = trust.Manager() + + def _get_filtered_domain(self, domain_id): + domain_ref = self.identity_api.get_domain(domain_id) + return {'id': domain_ref['id'], 'name': domain_ref['name']} + + def _get_filtered_project(self, project_id): + project_ref = self.identity_api.get_project(project_id) + filtered_project = { + 'id': project_ref['id'], + 'name': project_ref['name']} + filtered_project['domain'] = self._get_filtered_domain( + project_ref['domain_id']) + return filtered_project + + def _populate_scope(self, token_data, domain_id, project_id): + if 'domain' in token_data or 'project' in token_data: + # scope already exist, no need to populate it again + return + + if domain_id: + token_data['domain'] = self._get_filtered_domain(domain_id) + if project_id: + token_data['project'] = self._get_filtered_project(project_id) + + def _get_roles_for_user(self, user_id, domain_id, project_id): + roles = [] + if domain_id: + roles = self.identity_api.get_roles_for_user_and_domain( + user_id, domain_id) + if project_id: + roles = self.identity_api.get_roles_for_user_and_project( + user_id, project_id) + return [self.identity_api.get_role(role_id) for role_id in roles] + + def _populate_user(self, token_data, user_id, domain_id, project_id, + trust): + if 'user' in token_data: + # no need to repopulate user if it already exists + return + + user_ref = self.identity_api.get_user(user_id) + if CONF.trust.enabled and trust and 'OS-TRUST:trust' not in token_data: + trustor_user_ref = (self.identity_api.get_user( + trust['trustor_user_id'])) + if not trustor_user_ref['enabled']: + raise exception.Forbidden(_('Trustor is disabled.')) + if trust['impersonation']: + user_ref = trustor_user_ref + token_data['OS-TRUST:trust'] = ( + { + 'id': trust['id'], + 'trustor_user': {'id': trust['trustor_user_id']}, + 'trustee_user': {'id': trust['trustee_user_id']}, + 'impersonation': trust['impersonation'] + }) + filtered_user = { + 'id': user_ref['id'], + 'name': user_ref['name'], + 'domain': self._get_filtered_domain(user_ref['domain_id'])} + token_data['user'] = filtered_user + + def _populate_roles(self, token_data, user_id, domain_id, project_id, + trust): + if 'roles' in token_data: + # no need to repopulate roles + return + + if CONF.trust.enabled and trust: + token_user_id = trust['trustor_user_id'] + token_project_id = trust['project_id'] + #trusts do not support domains yet + token_domain_id = None + else: + token_user_id = user_id + token_project_id = project_id + token_domain_id = domain_id + + if token_domain_id or token_project_id: + roles = self._get_roles_for_user(token_user_id, + token_domain_id, + token_project_id) + filtered_roles = [] + if CONF.trust.enabled and trust: + for trust_role in trust['roles']: + match_roles = [x for x in roles + if x['id'] == trust_role['id']] + if match_roles: + filtered_roles.append(match_roles[0]) + else: + raise exception.Forbidden( + _('Trustee has no delegated roles.')) + else: + for role in roles: + filtered_roles.append({'id': role['id'], + 'name': role['name']}) + + # user has no project or domain roles, therefore access denied + if not filtered_roles: + if token_project_id: + msg = _('User %(user_id)s has no access ' + 'to project %(project_id)s') % { + 'user_id': user_id, + 'project_id': token_project_id} + else: + msg = _('User %(user_id)s has no access ' + 'to domain %(domain_id)s') % { + 'user_id': user_id, + 'domain_id': token_domain_id} + LOG.debug(msg) + raise exception.Unauthorized(msg) + + token_data['roles'] = filtered_roles + + def _populate_service_catalog(self, token_data, user_id, + domain_id, project_id, trust): + if 'catalog' in token_data: + # no need to repopulate service catalog + return + + if CONF.trust.enabled and trust: + user_id = trust['trustor_user_id'] + if project_id or domain_id: + try: + service_catalog = self.catalog_api.get_v3_catalog( + user_id, project_id) + # TODO(ayoung): KVS backend needs a sample implementation + except exception.NotImplemented: + service_catalog = {} + # TODO(gyee): v3 service catalog is not quite completed yet + # TODO(ayoung): Enforce Endpoints for trust + token_data['catalog'] = service_catalog + + def _populate_token_dates(self, token_data, expires=None, trust=None): + if not expires: + expires = token.default_expire_time() + if not isinstance(expires, basestring): + expires = timeutils.isotime(expires, subsecond=True) + token_data['expires_at'] = expires + token_data['issued_at'] = timeutils.isotime(subsecond=True) + + def get_token_data(self, user_id, method_names, extras, + domain_id=None, project_id=None, expires=None, + trust=None, token=None, include_catalog=True, + bind=None): + token_data = {'methods': method_names, + 'extras': extras} + + # We've probably already written these to the token + if token: + for x in ('roles', 'user', 'catalog', 'project', 'domain'): + if x in token: + token_data[x] = token[x] + + if CONF.trust.enabled and trust: + if user_id != trust['trustee_user_id']: + raise exception.Forbidden(_('User is not a trustee.')) + + if bind: + token_data['bind'] = bind + + self._populate_scope(token_data, domain_id, project_id) + self._populate_user(token_data, user_id, domain_id, project_id, trust) + self._populate_roles(token_data, user_id, domain_id, project_id, trust) + if include_catalog: + self._populate_service_catalog(token_data, user_id, domain_id, + project_id, trust) + self._populate_token_dates(token_data, expires=expires, trust=trust) + return {'token': token_data} + + +@dependency.requires('token_api', 'identity_api', 'catalog_api') +class Provider(token.provider.Provider): + def __init__(self, *args, **kwargs): + super(Provider, self).__init__(*args, **kwargs) + if CONF.trust.enabled: + self.trust_api = trust.Manager() + self.v3_token_data_helper = V3TokenDataHelper() + self.v2_token_data_helper = V2TokenDataHelper() + + def get_token_version(self, token_data): + if token_data and isinstance(token_data, dict): + if 'access' in token_data: + return token.provider.V2 + if 'token' in token_data and 'methods' in token_data['token']: + return token.provider.V3 + raise token.provider.UnsupportedTokenVersionException() + + def _get_token_id(self, token_data): + return uuid.uuid4().hex + + def _issue_v2_token(self, **kwargs): + token_data = self.v2_token_data_helper.get_token_data(**kwargs) + token_id = self._get_token_id(token_data) + token_data['access']['token']['id'] = token_id + try: + expiry = token_data['access']['token']['expires'] + token_ref = kwargs.get('token_ref') + if isinstance(expiry, basestring): + expiry = timeutils.normalize_time( + timeutils.parse_isotime(expiry)) + data = dict(key=token_id, + id=token_id, + expires=expiry, + user=token_ref['user'], + tenant=token_ref['tenant'], + metadata=token_ref['metadata'], + token_data=token_data, + bind=token_ref.get('bind'), + trust_id=token_ref['metadata'].get('trust_id')) + self.token_api.create_token(token_id, data) + except Exception: + exc_info = sys.exc_info() + # an identical token may have been created already. + # if so, return the token_data as it is also identical + try: + self.token_api.get_token(token_id) + except exception.TokenNotFound: + raise exc_info[0], exc_info[1], exc_info[2] + + return (token_id, token_data) + + def _issue_v3_token(self, **kwargs): + user_id = kwargs.get('user_id') + method_names = kwargs.get('method_names') + expires_at = kwargs.get('expires_at') + project_id = kwargs.get('project_id') + domain_id = kwargs.get('domain_id') + auth_context = kwargs.get('auth_context') + trust = kwargs.get('trust') + metadata_ref = kwargs.get('metadata_ref') + include_catalog = kwargs.get('include_catalog') + # for V2, trust is stashed in metadata_ref + if (CONF.trust.enabled and not trust and metadata_ref and + 'trust_id' in metadata_ref): + trust = self.trust_api.get_trust(metadata_ref['trust_id']) + token_data = self.v3_token_data_helper.get_token_data( + user_id, + method_names, + auth_context.get('extras') if auth_context else None, + domain_id=domain_id, + project_id=project_id, + expires=expires_at, + trust=trust, + bind=auth_context.get('bind') if auth_context else None, + include_catalog=include_catalog) + + token_id = self._get_token_id(token_data) + try: + expiry = token_data['token']['expires_at'] + if isinstance(expiry, basestring): + expiry = timeutils.normalize_time( + timeutils.parse_isotime(expiry)) + # FIXME(gyee): is there really a need to store roles in metadata? + role_ids = [] + metadata_ref = kwargs.get('metadata_ref', {}) + if 'project' in token_data['token']: + # project-scoped token, fill in the v2 token data + # all we care are the role IDs + role_ids = [r['id'] for r in token_data['token']['roles']] + metadata_ref = {'roles': role_ids} + if trust: + metadata_ref.setdefault('trust_id', trust['id']) + metadata_ref.setdefault('trustee_user_id', + trust['trustee_user_id']) + data = dict(key=token_id, + id=token_id, + expires=expiry, + user=token_data['token']['user'], + tenant=token_data['token'].get('project'), + metadata=metadata_ref, + token_data=token_data, + trust_id=trust['id'] if trust else None) + self.token_api.create_token(token_id, data) + except Exception: + exc_info = sys.exc_info() + # an identical token may have been created already. + # if so, return the token_data as it is also identical + try: + self.token_api.get_token(token_id) + except exception.TokenNotFound: + raise exc_info[0], exc_info[1], exc_info[2] + + return (token_id, token_data) + + def issue_token(self, version='v3.0', **kwargs): + if version == token.provider.V3: + return self._issue_v3_token(**kwargs) + elif version == token.provider.V2: + return self._issue_v2_token(**kwargs) + raise token.provider.UnsupportedTokenVersionException + + def _verify_token(self, token_id, belongs_to=None): + """Verify the given token and return the token_ref.""" + token_ref = self.token_api.get_token(token_id) + assert token_ref + if belongs_to: + assert (token_ref['tenant'] and + token_ref['tenant']['id'] == belongs_to) + return token_ref + + def revoke_token(self, token_id): + self.token_api.delete_token(token_id=token_id) + + def _assert_default_domain(self, token_ref): + """Make sure we are operating on default domain only.""" + if (token_ref.get('token_data') and + self.get_token_version(token_ref.get('token_data')) == + token.provider.V3): + # this is a V3 token + msg = _('Non-default domain is not supported') + # user in a non-default is prohibited + if (token_ref['token_data']['token']['user']['domain']['id'] != + DEFAULT_DOMAIN_ID): + raise exception.Unauthorized(msg) + # domain scoping is prohibited + if token_ref['token_data']['token'].get('domain'): + raise exception.Unauthorized( + _('Domain scoped token is not supported')) + # project in non-default domain is prohibited + if token_ref['token_data']['token'].get('project'): + project = token_ref['token_data']['token']['project'] + project_domain_id = project['domain']['id'] + # scoped to project in non-default domain is prohibited + if project_domain_id != DEFAULT_DOMAIN_ID: + raise exception.Unauthorized(msg) + # if token is scoped to trust, both trustor and trustee must + # be in the default domain. Furthermore, the delegated project + # must also be in the default domain + metadata_ref = token_ref['metadata'] + if CONF.trust.enabled and 'trust_id' in metadata_ref: + trust_ref = self.trust_api.get_trust(metadata_ref['trust_id']) + trustee_user_ref = self.identity_api.get_user( + trust_ref['trustee_user_id']) + if trustee_user_ref['domain_id'] != DEFAULT_DOMAIN_ID: + raise exception.Unauthorized(msg) + trustor_user_ref = self.identity_api.get_user( + trust_ref['trustor_user_id']) + if trustor_user_ref['domain_id'] != DEFAULT_DOMAIN_ID: + raise exception.Unauthorized(msg) + project_ref = self.identity_api.get_project( + trust_ref['project_id']) + if project_ref['domain_id'] != DEFAULT_DOMAIN_ID: + raise exception.Unauthorized(msg) + + def _validate_v2_token(self, token_id, belongs_to=None, **kwargs): + try: + token_ref = self._verify_token(token_id, belongs_to=belongs_to) + self._assert_default_domain(token_ref) + # FIXME(gyee): performance or correctness? Should we return the + # cached token or reconstruct it? Obviously if we are going with + # the cached token, any role, project, or domain name changes + # will not be reflected. One may argue that with PKI tokens, + # we are essentially doing cached token validation anyway. + # Lets go with the cached token strategy. Since token + # management layer is now pluggable, one can always provide + # their own implementation to suit their needs. + token_data = token_ref.get('token_data') + if (not token_data or + self.get_token_version(token_data) != + token.provider.V2): + # token is created by old v2 logic + metadata_ref = token_ref['metadata'] + role_refs = [] + for role_id in metadata_ref.get('roles', []): + role_refs.append(self.identity_api.get_role(role_id)) + + # Get a service catalog if possible + # This is needed for on-behalf-of requests + catalog_ref = None + if token_ref.get('tenant'): + catalog_ref = self.catalog_api.get_catalog( + token_ref['user']['id'], + token_ref['tenant']['id'], + metadata_ref) + token_data = self.v2_token_data_helper.get_token_data( + token_ref=token_ref, + roles_ref=role_refs, + catalog_ref=catalog_ref) + return token_data + except AssertionError as e: + LOG.exception(_('Failed to validate token')) + raise exception.Unauthorized(e) + + def _validate_v3_token(self, token_id): + token_ref = self._verify_token(token_id) + # FIXME(gyee): performance or correctness? Should we return the + # cached token or reconstruct it? Obviously if we are going with + # the cached token, any role, project, or domain name changes + # will not be reflected. One may argue that with PKI tokens, + # we are essentially doing cached token validation anyway. + # Lets go with the cached token strategy. Since token + # management layer is now pluggable, one can always provide + # their own implementation to suit their needs. + token_data = token_ref.get('token_data') + if not token_data or 'token' not in token_data: + # token ref is created by V2 API + project_id = None + project_ref = token_ref.get('tenant') + if project_ref: + project_id = project_ref['id'] + token_data = self.v3_token_data_helper.get_token_data( + token_ref['user']['id'], + ['password', 'token'], + {}, + project_id=project_id, + bind=token_ref.get('bind'), + expires=token_ref['expires']) + return token_data + + def validate_token(self, token_id, belongs_to=None, version='v3.0'): + try: + if version == token.provider.V3: + return self._validate_v3_token(token_id) + elif version == token.provider.V2: + return self._validate_v2_token(token_id, + belongs_to=belongs_to) + raise token.provider.UnsupportedTokenVersionException() + except exception.TokenNotFound as e: + LOG.exception(_('Failed to verify token')) + raise exception.Unauthorized(e) + + def check_token(self, token_id, belongs_to=None, + version='v3.0', **kwargs): + try: + token_ref = self._verify_token(token_id, belongs_to=belongs_to) + if version == token.provider.V2: + self._assert_default_domain(token_ref) + except exception.TokenNotFound as e: + LOG.exception(_('Failed to verify token')) + raise exception.Unauthorized(e) diff --git a/keystone/trust/controllers.py b/keystone/trust/controllers.py index 7be6e8fd..7a94fe29 100644 --- a/keystone/trust/controllers.py +++ b/keystone/trust/controllers.py @@ -35,6 +35,21 @@ class TrustV3(controller.V3Controller): collection_name = "trusts" member_name = "trust" + @classmethod + def base_url(cls, path=None): + endpoint = CONF.public_endpoint % CONF + + # allow a missing trailing slash in the config + if endpoint[-1] != '/': + endpoint += '/' + + url = endpoint + 'v3/OS-TRUST' + + if path: + return url + path + else: + return url + '/' + cls.collection_name + def _get_user_id(self, context): if 'token_id' in context: token_id = context['token_id'] @@ -78,8 +93,7 @@ class TrustV3(controller.V3Controller): trust_full_roles.append(full_role) trust['roles'] = trust_full_roles trust['roles_links'] = { - 'self': (CONF.public_endpoint % CONF + - "trusts/%s/roles" % trust['id']), + 'self': (self.base_url() + "/%s/roles" % trust['id']), 'next': None, 'previous': None} diff --git a/openstack-common.conf b/openstack-common.conf index 170f200f..17062942 100644 --- a/openstack-common.conf +++ b/openstack-common.conf @@ -1,6 +1,7 @@ [DEFAULT] # The list of modules to copy from openstack-common +module=crypto module=importutils module=install_venv_common module=jsonutils diff --git a/requirements.txt b/requirements.txt index 45054f24..e54bb6a0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,5 +13,5 @@ sqlalchemy-migrate>=0.7.2 passlib lxml iso8601>=0.1.4 -python-keystoneclient>=0.2.1,<0.3 +python-keystoneclient>=0.3.0 oslo.config>=1.1.0 @@ -1,5 +1,6 @@ [metadata] name = keystone +version = 2013.2 summary = OpenStack Identity description-file = README.rst diff --git a/test-requirements.txt b/test-requirements.txt index 0f772cb0..e0534ca4 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -11,22 +11,31 @@ pysqlite python-memcached # Optional backend: LDAP -python-ldap==2.3.13 # authenticate against an existing LDAP server +# authenticate against an existing LDAP server +python-ldap==2.3.13 # Testing -coverage # computes code coverage percentages -mox # mock object framework -nose # for test discovery and console feedback +# computes code coverage percentages +coverage +# mock object framework +mox +# for test discovery and console feedback +nose nosexcover openstack.nose_plugin nosehtmloutput -Sphinx>=1.1.2 # required to build documentation -unittest2 # backport of unittest lib in python 2.7 -webtest # test wsgi apps without starting an http server +# required to build documentation +Sphinx>=1.1.2 +# backport of unittest lib in python 2.7 +unittest2 +# test wsgi apps without starting an http server +webtest # for python-keystoneclient -httplib2 # keystoneclient <0.2.1 -requests>=1.0.0 # replaces httplib2 in keystoneclient >=0.2.1 +# keystoneclient <0.2.1 +httplib2 +# replaces httplib2 in keystoneclient >=0.2.1 +requests>=1.0.0 keyring # swift_auth test dependencies @@ -35,3 +44,6 @@ netifaces # For translations processing Babel + +# For documentation +oslo.sphinx diff --git a/tests/_ldap_livetest.py b/tests/_ldap_livetest.py index 0943f8d0..ead54ea7 100644 --- a/tests/_ldap_livetest.py +++ b/tests/_ldap_livetest.py @@ -16,7 +16,6 @@ import ldap import ldap.modlist -import nose.exc import subprocess from keystone.common import ldap as ldap_common @@ -68,9 +67,6 @@ class LiveLDAPIdentity(test_backend_ldap.LDAPIdentity): create_object(CONF.ldap.tenant_tree_dn, {'objectclass': 'organizationalUnit', 'ou': 'Projects'}) - create_object(CONF.ldap.domain_tree_dn, - {'objectclass': 'organizationalUnit', - 'ou': 'Domains'}) create_object(CONF.ldap.group_tree_dn, {'objectclass': 'organizationalUnit', 'ou': 'UserGroups'}) @@ -92,7 +88,7 @@ class LiveLDAPIdentity(test_backend_ldap.LDAPIdentity): test.TestCase.tearDown(self) def test_user_enable_attribute_mask(self): - raise nose.exc.SkipTest('Test is for Active Directory Only') + self.skipTest('Test is for Active Directory Only') def test_ldap_dereferencing(self): alt_users_ldif = {'objectclass': ['top', 'organizationalUnit'], diff --git a/tests/_sql_livetest.py b/tests/_sql_livetest.py index d9890979..a271ce7c 100644 --- a/tests/_sql_livetest.py +++ b/tests/_sql_livetest.py @@ -35,3 +35,11 @@ class MysqlMigrateTests(test_sql_upgrade.SqlUpgradeTests): _config_file_list[:]) files.append("backend_mysql.conf") return files + + +class Db2MigrateTests(test_sql_upgrade.SqlUpgradeTests): + def config_files(self): + files = (test_sql_upgrade.SqlUpgradeTests. + _config_file_list[:]) + files.append("backend_db2.conf") + return files diff --git a/tests/auth_plugin_external_disabled.conf b/tests/auth_plugin_external_disabled.conf new file mode 100644 index 00000000..fed281d4 --- /dev/null +++ b/tests/auth_plugin_external_disabled.conf @@ -0,0 +1,2 @@ +[auth] +methods = password, token diff --git a/tests/auth_plugin_external_domain.conf b/tests/auth_plugin_external_domain.conf new file mode 100644 index 00000000..b7be122f --- /dev/null +++ b/tests/auth_plugin_external_domain.conf @@ -0,0 +1,3 @@ +[auth] +methods = external, password, token +external = keystone.auth.plugins.external.ExternalDomain diff --git a/tests/backend_db2.conf b/tests/backend_db2.conf new file mode 100644 index 00000000..44032255 --- /dev/null +++ b/tests/backend_db2.conf @@ -0,0 +1,4 @@ +#Used for running the Migrate tests against a live DB2 Server +#See _sql_livetest.py +[sql] +connection = ibm_db_sa://keystone:keystone@/staktest?charset=utf8 diff --git a/tests/backend_ldap_sql.conf b/tests/backend_ldap_sql.conf new file mode 100644 index 00000000..8dcfa40d --- /dev/null +++ b/tests/backend_ldap_sql.conf @@ -0,0 +1,36 @@ +[sql] +connection = sqlite:// +#For a file based sqlite use +#connection = sqlite:////tmp/keystone.db +#To Test MySQL: +#connection = mysql://keystone:keystone@localhost/keystone?charset=utf8 +#To Test PostgreSQL: +#connection = postgresql://keystone:keystone@localhost/keystone?client_encoding=utf8 +idle_timeout = 200 + +[ldap] +url = fake://memory +user = cn=Admin +password = password +suffix = cn=example,cn=com + +[identity] +driver = keystone.identity.backends.ldap.Identity + +[assignment] +driver = keystone.assignment.backends.sql.Assignment + +[token] +driver = keystone.token.backends.sql.Token + +[ec2] +driver = keystone.contrib.ec2.backends.sql.Ec2 + +[catalog] +driver = keystone.catalog.backends.sql.Catalog + +[policy] +driver = keystone.policy.backends.sql.Policy + +[trust] +driver = keystone.trust.backends.sql.Trust diff --git a/tests/backend_liveldap.conf b/tests/backend_liveldap.conf index abcd441d..297d96d6 100644 --- a/tests/backend_liveldap.conf +++ b/tests/backend_liveldap.conf @@ -6,11 +6,9 @@ suffix = dc=openstack,dc=org group_tree_dn = ou=UserGroups,dc=openstack,dc=org role_tree_dn = ou=Roles,dc=openstack,dc=org tenant_tree_dn = ou=Projects,dc=openstack,dc=org -domain_tree_dn = ou=Domains,dc=openstack,dc=org user_tree_dn = ou=Users,dc=openstack,dc=org tenant_enabled_emulation = True user_enabled_emulation = True -domain_enabled_emulation = True user_mail_attribute = mail use_dumb_member = True diff --git a/tests/backend_sql_disk.conf b/tests/backend_sql_disk.conf index a4be9117..0f8dfea7 100644 --- a/tests/backend_sql_disk.conf +++ b/tests/backend_sql_disk.conf @@ -1,2 +1,2 @@ [sql] -connection = sqlite:///test.db +connection = sqlite:///tmp/test.db diff --git a/tests/backend_tls_liveldap.conf b/tests/backend_tls_liveldap.conf index 0c9d7f23..409af674 100644 --- a/tests/backend_tls_liveldap.conf +++ b/tests/backend_tls_liveldap.conf @@ -6,11 +6,9 @@ suffix = dc=openstack,dc=org group_tree_dn = ou=UserGroups,dc=openstack,dc=org role_tree_dn = ou=Roles,dc=openstack,dc=org tenant_tree_dn = ou=Projects,dc=openstack,dc=org -domain_tree_dn = ou=Domains,dc=openstack,dc=org user_tree_dn = ou=Users,dc=openstack,dc=org tenant_enabled_emulation = True user_enabled_emulation = True -domain_enabled_emulation = True user_mail_attribute = mail use_dumb_member = True use_tls = True diff --git a/tests/default_fixtures.py b/tests/default_fixtures.py index 256bb4b7..2695da88 100644 --- a/tests/default_fixtures.py +++ b/tests/default_fixtures.py @@ -17,6 +17,7 @@ # NOTE(dolph): please try to avoid additional fixtures if possible; test suite # performance may be negatively affected. +from keystone import assignment from keystone import config @@ -54,7 +55,7 @@ TENANTS = [ } ] -# NOTE(ja): a role of keystone_admin and attribute "is_admin" is done in setUp +# NOTE(ja): a role of keystone_admin is done in setUp USERS = [ { 'id': 'foo', @@ -95,13 +96,6 @@ USERS = [ } ] -METADATA = [ - { - 'user_id': 'sna', - 'tenant_id': 'mtu', - } -] - ROLES = [ { 'id': 'admin', @@ -125,16 +119,6 @@ ROLES = [ 'id': 'service', 'name': 'Service', } - - ] -DOMAINS = [ - { - 'id': DEFAULT_DOMAIN_ID, - 'name': 'Default', - 'enabled': True, - 'description': 'Owns users and tenants (i.e. projects) available ' - 'on Identity API v2.' - } -] +DOMAINS = [assignment.DEFAULT_DOMAIN] diff --git a/tests/test_auth.py b/tests/test_auth.py index b14977b9..db5314be 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -68,6 +68,10 @@ class AuthTest(test.TestCase): self.load_backends() self.load_fixtures(default_fixtures) + # need to register the token provider first because auth controller + # depends on it + token.provider.Manager() + self.controller = token.controllers.Auth() def assertEqualTokens(self, a, b): @@ -369,6 +373,33 @@ class AuthWithToken(AuthTest): dict(is_admin=True, query_string={'belongsTo': 'BAR'}), token_id=scoped_token_id) + def test_token_auth_with_binding(self): + CONF.token.bind = ['kerberos'] + body_dict = _build_user_auth() + context = {'REMOTE_USER': 'FOO', 'AUTH_TYPE': 'Negotiate'} + unscoped_token = self.controller.authenticate(context, body_dict) + + # the token should have bind information in it + bind = unscoped_token['access']['token']['bind'] + self.assertEqual(bind['kerberos'], 'FOO') + + body_dict = _build_user_auth( + token=unscoped_token['access']['token'], + tenant_name='BAR') + + # using unscoped token without remote user context fails + self.assertRaises( + exception.Unauthorized, + self.controller.authenticate, + {}, body_dict) + + # using token with remote user context succeeds + scoped_token = self.controller.authenticate(context, body_dict) + + # the bind information should be carried over from the original token + bind = scoped_token['access']['token']['bind'] + self.assertEqual(bind['kerberos'], 'FOO') + class AuthWithPasswordCredentials(AuthTest): def setUp(self): @@ -427,6 +458,13 @@ class AuthWithPasswordCredentials(AuthTest): self.controller.authenticate, {}, body_dict) + def test_bind_without_remote_user(self): + CONF.token.bind = ['kerberos'] + body_dict = _build_user_auth(username='FOO', password='foo2', + tenant_name='BAR') + token = self.controller.authenticate({}, body_dict) + self.assertNotIn('bind', token['access']['token']) + class AuthWithRemoteUser(AuthTest): def setUp(self): @@ -494,6 +532,20 @@ class AuthWithRemoteUser(AuthTest): {'REMOTE_USER': uuid.uuid4().hex}, body_dict) + def test_bind_with_kerberos(self): + CONF.token.bind = ['kerberos'] + kerb = {'REMOTE_USER': 'FOO', 'AUTH_TYPE': 'Negotiate'} + body_dict = _build_user_auth(tenant_name="BAR") + token = self.controller.authenticate(kerb, body_dict) + self.assertEqual(token['access']['token']['bind']['kerberos'], 'FOO') + + def test_bind_without_config_opt(self): + CONF.token.bind = ['x509'] + kerb = {'REMOTE_USER': 'FOO', 'AUTH_TYPE': 'Negotiate'} + body_dict = _build_user_auth(tenant_name='BAR') + token = self.controller.authenticate(kerb, body_dict) + self.assertNotIn('bind', token['access']['token']) + class AuthWithTrust(AuthTest): def setUp(self): @@ -566,6 +618,10 @@ class AuthWithTrust(AuthTest): role_ids = [self.role_browser['id'], self.role_member['id']] self.assertTrue(timeutils.parse_strtime(self.new_trust['expires_at'], fmt=TIME_FORMAT)) + self.assertIn('http://localhost:5000/v3/OS-TRUST/', + self.new_trust['links']['self']) + self.assertIn('http://localhost:5000/v3/OS-TRUST/', + self.new_trust['roles_links']['self']) for role in self.new_trust['roles']: self.assertIn(role['id'], role_ids) @@ -621,7 +677,7 @@ class AuthWithTrust(AuthTest): 'project': { 'id': self.tenant_baz['id']}}} auth_response = (self.auth_v3_controller.authenticate_for_token - ({}, v3_password_data)) + ({'query_string': {}}, v3_password_data)) token = auth_response.headers['X-Subject-Token'] v3_req_with_trust = { @@ -631,7 +687,7 @@ class AuthWithTrust(AuthTest): "scope": { "OS-TRUST:trust": {"id": self.new_trust['id']}}} token_auth_response = (self.auth_v3_controller.authenticate_for_token - ({}, v3_req_with_trust)) + ({'query_string': {}}, v3_req_with_trust)) return token_auth_response def test_create_v3_token_from_trust(self): @@ -653,14 +709,14 @@ class AuthWithTrust(AuthTest): def test_v3_trust_token_get_token_fails(self): auth_response = self.fetch_v3_token_from_trust() trust_token = auth_response.headers['X-Subject-Token'] - v3_token_data = { - "methods": ["token"], - "token": {"id": trust_token} - } + v3_token_data = {'identity': { + 'methods': ['token'], + 'token': {'id': trust_token} + }} self.assertRaises( - exception.Unauthorized, + exception.Forbidden, self.auth_v3_controller.authenticate_for_token, - {}, v3_token_data) + {'query_string': {}}, v3_token_data) def test_token_from_trust(self): auth_response = self.fetch_v2_token_from_trust() diff --git a/tests/test_auth_plugin.conf b/tests/test_auth_plugin.conf index efe4bcb4..edec8f79 100644 --- a/tests/test_auth_plugin.conf +++ b/tests/test_auth_plugin.conf @@ -1,3 +1,3 @@ [auth] -methods = password,token,simple-challenge-response +methods = external,password,token,simple-challenge-response simple-challenge-response = challenge_response_method.SimpleChallengeResponse diff --git a/tests/test_auth_plugin.py b/tests/test_auth_plugin.py index 22357471..d158ec46 100644 --- a/tests/test_auth_plugin.py +++ b/tests/test_auth_plugin.py @@ -20,6 +20,7 @@ from keystone import test from keystone import auth from keystone import exception +from keystone import token # for testing purposes only @@ -49,6 +50,11 @@ class TestAuthPlugin(test.TestCase): test.testsdir('test_auth_plugin.conf')]) self.load_backends() auth.controllers.AUTH_METHODS[METHOD_NAME] = SimpleChallengeResponse() + + # need to register the token provider first because auth controller + # depends on it + token.provider.Manager() + self.api = auth.controllers.Auth() def test_unsupported_auth_method(self): diff --git a/tests/test_backend.py b/tests/test_backend.py index ea40cd8b..7e4d820e 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -62,39 +62,17 @@ class IdentityTests(object): self.assertRaises(AssertionError, self.identity_api.authenticate, user_id=uuid.uuid4().hex, - tenant_id=self.tenant_bar['id'], password=self.user_foo['password']) def test_authenticate_bad_password(self): self.assertRaises(AssertionError, self.identity_api.authenticate, user_id=self.user_foo['id'], - tenant_id=self.tenant_bar['id'], password=uuid.uuid4().hex) - def test_authenticate_bad_project(self): - self.assertRaises(AssertionError, - self.identity_api.authenticate, - user_id=self.user_foo['id'], - tenant_id=uuid.uuid4().hex, - password=self.user_foo['password']) - - def test_authenticate_no_project(self): - user_ref, tenant_ref, metadata_ref = self.identity_api.authenticate( - user_id=self.user_foo['id'], - password=self.user_foo['password']) - # NOTE(termie): the password field is left in user_foo to make - # it easier to authenticate in tests, but should - # not be returned by the api - self.user_foo.pop('password') - self.assertDictEqual(user_ref, self.user_foo) - self.assert_(tenant_ref is None) - self.assert_(not metadata_ref) - def test_authenticate(self): - user_ref, tenant_ref, metadata_ref = self.identity_api.authenticate( + user_ref = self.identity_api.authenticate( user_id=self.user_sna['id'], - tenant_id=self.tenant_bar['id'], password=self.user_sna['password']) # NOTE(termie): the password field is left in user_foo to make # it easier to authenticate in tests, but should @@ -102,21 +80,8 @@ class IdentityTests(object): self.user_sna.pop('password') self.user_sna['enabled'] = True self.assertDictEqual(user_ref, self.user_sna) - self.assertDictEqual(tenant_ref, self.tenant_bar) - metadata_ref.pop('roles') - self.assertDictEqual(metadata_ref, self.metadata_snamtu) - - def test_authenticate_role_return(self): - self.identity_api.add_role_to_user_and_project( - self.user_foo['id'], self.tenant_baz['id'], self.role_admin['id']) - user_ref, tenant_ref, metadata_ref = self.identity_api.authenticate( - user_id=self.user_foo['id'], - tenant_id=self.tenant_baz['id'], - password=self.user_foo['password']) - self.assertIn('roles', metadata_ref) - self.assertIn(self.role_admin['id'], metadata_ref['roles']) - def test_authenticate_no_metadata(self): + def test_authenticate_and_get_roles_no_metadata(self): user = { 'id': 'no_meta', 'name': 'NO_META', @@ -126,18 +91,18 @@ class IdentityTests(object): self.identity_api.create_user(user['id'], user) self.identity_api.add_user_to_project(self.tenant_baz['id'], user['id']) - user_ref, tenant_ref, metadata_ref = self.identity_api.authenticate( + user_ref = self.identity_api.authenticate( user_id=user['id'], - tenant_id=self.tenant_baz['id'], password=user['password']) # NOTE(termie): the password field is left in user_foo to make # it easier to authenticate in tests, but should # not be returned by the api user.pop('password') - self.assertEquals(metadata_ref, {"roles": - [CONF.member_role_id]}) self.assertDictContainsSubset(user, user_ref) - self.assertDictEqual(tenant_ref, self.tenant_baz) + role_list = self.identity_api.get_roles_for_user_and_project( + user['id'], self.tenant_baz['id']) + self.assertEqual(len(role_list), 1) + self.assertIn(CONF.member_role_id, role_list) def test_password_hashed(self): user_ref = self.identity_api._get_user(self.user_foo['id']) @@ -153,26 +118,25 @@ class IdentityTests(object): self.assertEqual(unicode_name, ref['name']) def test_get_project(self): - tenant_ref = self.identity_api.get_project( - tenant_id=self.tenant_bar['id']) + tenant_ref = self.identity_api.get_project(self.tenant_bar['id']) self.assertDictEqual(tenant_ref, self.tenant_bar) def test_get_project_404(self): self.assertRaises(exception.ProjectNotFound, self.identity_api.get_project, - tenant_id=uuid.uuid4().hex) + uuid.uuid4().hex) def test_get_project_by_name(self): tenant_ref = self.identity_api.get_project_by_name( - tenant_name=self.tenant_bar['name'], - domain_id=DEFAULT_DOMAIN_ID) + self.tenant_bar['name'], + DEFAULT_DOMAIN_ID) self.assertDictEqual(tenant_ref, self.tenant_bar) def test_get_project_by_name_404(self): self.assertRaises(exception.ProjectNotFound, self.identity_api.get_project_by_name, - tenant_name=uuid.uuid4().hex, - domain_id=DEFAULT_DOMAIN_ID) + uuid.uuid4().hex, + DEFAULT_DOMAIN_ID) def test_get_project_users(self): tenant_ref = self.identity_api.get_project_users(self.tenant_baz['id']) @@ -187,10 +151,10 @@ class IdentityTests(object): def test_get_project_users_404(self): self.assertRaises(exception.ProjectNotFound, self.identity_api.get_project_users, - tenant_id=uuid.uuid4().hex) + uuid.uuid4().hex) def test_get_user(self): - user_ref = self.identity_api.get_user(user_id=self.user_foo['id']) + user_ref = self.identity_api.get_user(self.user_foo['id']) # NOTE(termie): the password field is left in user_foo to make # it easier to authenticate in tests, but should # not be returned by the api @@ -200,12 +164,12 @@ class IdentityTests(object): def test_get_user_404(self): self.assertRaises(exception.UserNotFound, self.identity_api.get_user, - user_id=uuid.uuid4().hex) + uuid.uuid4().hex) def test_get_user_by_name(self): user_ref = self.identity_api.get_user_by_name( - user_name=self.user_foo['name'], - domain_id=DEFAULT_DOMAIN_ID) + self.user_foo['name'], DEFAULT_DOMAIN_ID) + # NOTE(termie): the password field is left in user_foo to make # it easier to authenticate in tests, but should # not be returned by the api @@ -215,38 +179,18 @@ class IdentityTests(object): def test_get_user_by_name_404(self): self.assertRaises(exception.UserNotFound, self.identity_api.get_user_by_name, - user_name=uuid.uuid4().hex, - domain_id=DEFAULT_DOMAIN_ID) - - def test_get_metadata(self): - metadata_ref = self.identity_api.get_metadata( - user_id=self.user_sna['id'], - tenant_id=self.tenant_bar['id']) - metadata_ref.pop('roles') - self.assertDictEqual(metadata_ref, self.metadata_snamtu) - - def test_get_metadata_404(self): - # FIXME(dolph): these exceptions could be more specific - self.assertRaises(exception.NotFound, - self.identity_api.get_metadata, - user_id=uuid.uuid4().hex, - tenant_id=self.tenant_bar['id']) - - self.assertRaises(exception.NotFound, - self.identity_api.get_metadata, - user_id=self.user_foo['id'], - tenant_id=uuid.uuid4().hex) + uuid.uuid4().hex, + DEFAULT_DOMAIN_ID) def test_get_role(self): - role_ref = self.identity_api.get_role( - role_id=self.role_admin['id']) + role_ref = self.identity_api.get_role(self.role_admin['id']) role_ref_dict = dict((x, role_ref[x]) for x in role_ref) self.assertDictEqual(role_ref_dict, self.role_admin) def test_get_role_404(self): self.assertRaises(exception.RoleNotFound, self.identity_api.get_role, - role_id=uuid.uuid4().hex) + uuid.uuid4().hex) def test_create_duplicate_role_name_fails(self): role = {'id': 'fake1', @@ -482,6 +426,72 @@ class IdentityTests(object): self.identity_api.get_project, 'fake2') + def test_list_role_assignments_unfiltered(self): + """Test for unfiltered listing role assignments. + + Test Plan: + - Create a domain, with a user, group & project + - Find how many role assignments already exist (from default + fixtures) + - Create a grant of each type (user/group on project/domain) + - Check the number of assignments has gone up by 4 and that + the entries we added are in the list returned + + """ + new_domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.identity_api.create_domain(new_domain['id'], new_domain) + new_user = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, + 'password': uuid.uuid4().hex, 'enabled': True, + 'domain_id': new_domain['id']} + self.identity_api.create_user(new_user['id'], + new_user) + new_group = {'id': uuid.uuid4().hex, 'domain_id': new_domain['id'], + 'name': uuid.uuid4().hex} + self.identity_api.create_group(new_group['id'], new_group) + new_project = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex, + 'domain_id': new_domain['id']} + self.identity_api.create_project(new_project['id'], new_project) + + # First check how many role grant already exist + existing_assignments = len(self.identity_api.list_role_assignments()) + + # Now create the grants (roles are defined in default_fixtures) + self.identity_api.create_grant(user_id=new_user['id'], + domain_id=new_domain['id'], + role_id='member') + self.identity_api.create_grant(user_id=new_user['id'], + project_id=new_project['id'], + role_id='other') + self.identity_api.create_grant(group_id=new_group['id'], + domain_id=new_domain['id'], + role_id='admin') + self.identity_api.create_grant(group_id=new_group['id'], + project_id=new_project['id'], + role_id='admin') + + # Read back the list of assignments - check it is gone up by 4 + assignment_list = self.identity_api.list_role_assignments() + self.assertEquals(len(assignment_list), existing_assignments + 4) + + # Now check that each of our four new entries are in the list + self.assertIn( + {'user_id': new_user['id'], 'domain_id': new_domain['id'], + 'role_id': 'member'}, + assignment_list) + self.assertIn( + {'user_id': new_user['id'], 'project_id': new_project['id'], + 'role_id': 'other'}, + assignment_list) + self.assertIn( + {'group_id': new_group['id'], 'domain_id': new_domain['id'], + 'role_id': 'admin'}, + assignment_list) + self.assertIn( + {'group_id': new_group['id'], 'project_id': new_project['id'], + 'role_id': 'admin'}, + assignment_list) + def test_add_duplicate_role_grant(self): roles_ref = self.identity_api.get_roles_for_user_and_project( self.user_foo['id'], self.tenant_bar['id']) @@ -658,7 +668,7 @@ class IdentityTests(object): project_id=self.tenant_bar['id']) roles_ref_ids = [] - for i, ref in enumerate(roles_ref): + for ref in roles_ref: roles_ref_ids.append(ref['id']) self.assertIn(self.role_admin['id'], roles_ref_ids) self.assertIn('member', roles_ref_ids) @@ -1065,7 +1075,7 @@ class IdentityTests(object): project_id=project1['id']) roles_ref_ids = [] - for i, ref in enumerate(roles_ref): + for ref in roles_ref: roles_ref_ids.append(ref['id']) self.assertIn(role1['id'], roles_ref_ids) self.assertIn(role2['id'], roles_ref_ids) @@ -1081,7 +1091,7 @@ class IdentityTests(object): def test_multi_role_grant_by_user_group_on_project_domain(self): role_list = [] - for _ in range(8): + for _ in range(10): role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} self.identity_api.create_role(role['id'], role) role_list.append(role) @@ -1094,12 +1104,17 @@ class IdentityTests(object): group1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, 'domain_id': domain1['id'], 'enabled': True} self.identity_api.create_group(group1['id'], group1) + group2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, + 'domain_id': domain1['id'], 'enabled': True} + self.identity_api.create_group(group2['id'], group2) project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, 'domain_id': domain1['id']} self.identity_api.create_project(project1['id'], project1) self.identity_api.add_user_to_group(user1['id'], group1['id']) + self.identity_api.add_user_to_group(user1['id'], + group2['id']) roles_ref = self.identity_api.list_grants( user_id=user1['id'], @@ -1150,6 +1165,105 @@ class IdentityTests(object): self.assertIn(role_list[6], roles_ref) self.assertIn(role_list[7], roles_ref) + # Now test the alternate way of getting back lists of grants, + # where user and group roles are combined. These should match + # the above results. + combined_role_list = self.identity_api.get_roles_for_user_and_project( + user1['id'], project1['id']) + self.assertEquals(len(combined_role_list), 4) + self.assertIn(role_list[4]['id'], combined_role_list) + self.assertIn(role_list[5]['id'], combined_role_list) + self.assertIn(role_list[6]['id'], combined_role_list) + self.assertIn(role_list[7]['id'], combined_role_list) + + combined_role_list = self.identity_api.get_roles_for_user_and_domain( + user1['id'], domain1['id']) + self.assertEquals(len(combined_role_list), 4) + self.assertIn(role_list[0]['id'], combined_role_list) + self.assertIn(role_list[1]['id'], combined_role_list) + self.assertIn(role_list[2]['id'], combined_role_list) + self.assertIn(role_list[3]['id'], combined_role_list) + + def test_multi_group_grants_on_project_domain(self): + """Test multiple group roles for user on project and domain. + + Test Plan: + - Create 6 roles + - Create a domain, with a project, user and two groups + - Make the user a member of both groups + - Check no roles yet exit + - Assign a role to each user and both groups on both the + project and domain + - Get a list of effective roles for the user on both the + project and domain, checking we get back the correct three + roles + + """ + role_list = [] + for _ in range(6): + role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.identity_api.create_role(role['id'], role) + role_list.append(role) + domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.identity_api.create_domain(domain1['id'], domain1) + user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, + 'domain_id': domain1['id'], 'password': uuid.uuid4().hex, + 'enabled': True} + self.identity_api.create_user(user1['id'], user1) + group1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, + 'domain_id': domain1['id'], 'enabled': True} + self.identity_api.create_group(group1['id'], group1) + group2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, + 'domain_id': domain1['id'], 'enabled': True} + self.identity_api.create_group(group2['id'], group2) + project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, + 'domain_id': domain1['id']} + self.identity_api.create_project(project1['id'], project1) + + self.identity_api.add_user_to_group(user1['id'], + group1['id']) + self.identity_api.add_user_to_group(user1['id'], + group2['id']) + + roles_ref = self.identity_api.list_grants( + user_id=user1['id'], + project_id=project1['id']) + self.assertEquals(len(roles_ref), 0) + self.identity_api.create_grant(user_id=user1['id'], + domain_id=domain1['id'], + role_id=role_list[0]['id']) + self.identity_api.create_grant(group_id=group1['id'], + domain_id=domain1['id'], + role_id=role_list[1]['id']) + self.identity_api.create_grant(group_id=group2['id'], + domain_id=domain1['id'], + role_id=role_list[2]['id']) + self.identity_api.create_grant(user_id=user1['id'], + project_id=project1['id'], + role_id=role_list[3]['id']) + self.identity_api.create_grant(group_id=group1['id'], + project_id=project1['id'], + role_id=role_list[4]['id']) + self.identity_api.create_grant(group_id=group2['id'], + project_id=project1['id'], + role_id=role_list[5]['id']) + + # Read by the roles, ensuring we get the correct 3 roles for + # both project and domain + combined_role_list = self.identity_api.get_roles_for_user_and_project( + user1['id'], project1['id']) + self.assertEquals(len(combined_role_list), 3) + self.assertIn(role_list[3]['id'], combined_role_list) + self.assertIn(role_list[4]['id'], combined_role_list) + self.assertIn(role_list[5]['id'], combined_role_list) + + combined_role_list = self.identity_api.get_roles_for_user_and_domain( + user1['id'], domain1['id']) + self.assertEquals(len(combined_role_list), 3) + self.assertIn(role_list[0]['id'], combined_role_list) + self.assertIn(role_list[1]['id'], combined_role_list) + self.assertIn(role_list[2]['id'], combined_role_list) + def test_delete_role_with_user_and_group_grants(self): role1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} self.identity_api.create_role(role1['id'], role1) @@ -1655,6 +1769,30 @@ class IdentityTests(object): self.assertIn(self.tenant_bar['id'], project_ids) self.assertIn(self.tenant_baz['id'], project_ids) + def test_list_projects_for_domain(self): + project_ids = ([x['id'] for x in + self.assignment_api.list_projects(DEFAULT_DOMAIN_ID)]) + self.assertEquals(len(project_ids), 4) + self.assertIn(self.tenant_bar['id'], project_ids) + self.assertIn(self.tenant_baz['id'], project_ids) + self.assertIn(self.tenant_mtu['id'], project_ids) + self.assertIn(self.tenant_service['id'], project_ids) + + def test_list_projects_for_alternate_domain(self): + domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.assignment_api.create_domain(domain1['id'], domain1) + project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, + 'domain_id': domain1['id']} + self.assignment_api.create_project(project1['id'], project1) + project2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, + 'domain_id': domain1['id']} + self.assignment_api.create_project(project2['id'], project2) + project_ids = ([x['id'] for x in + self.assignment_api.list_projects(domain1['id'])]) + self.assertEquals(len(project_ids), 2) + self.assertIn(project1['id'], project_ids) + self.assertIn(project2['id'], project_ids) + def test_list_roles(self): roles = self.identity_api.list_roles() for test_role in default_fixtures.ROLES: @@ -2353,7 +2491,7 @@ class TrustTests(object): {'id': 'browser'}], trust_data['roles']) def test_list_trust_by_trustee(self): - for i in range(0, 3): + for i in range(3): self.create_sample_trust(uuid.uuid4().hex) trusts = self.trust_api.list_trusts_for_trustee(self.trustee['id']) self.assertEqual(len(trusts), 3) @@ -2362,7 +2500,7 @@ class TrustTests(object): self.assertEqual(len(trusts), 0) def test_list_trust_by_trustor(self): - for i in range(0, 3): + for i in range(3): self.create_sample_trust(uuid.uuid4().hex) trusts = self.trust_api.list_trusts_for_trustor(self.trustor['id']) self.assertEqual(len(trusts), 3) @@ -2371,7 +2509,7 @@ class TrustTests(object): self.assertEqual(len(trusts), 0) def test_list_trusts(self): - for i in range(0, 3): + for i in range(3): self.create_sample_trust(uuid.uuid4().hex) trusts = self.trust_api.list_trusts() self.assertEqual(len(trusts), 3) @@ -2579,3 +2717,164 @@ class PolicyTests(object): self.assertRaises(exception.PolicyNotFound, self.policy_api.delete_policy, uuid.uuid4().hex) + + +class InheritanceTests(object): + + def test_inherited_role_grants_for_user(self): + """Test inherited user roles. + + Test Plan: + - Enable OS-INHERIT extension + - Create 3 roles + - Create a domain, with a project and a user + - Check no roles yet exit + - Assign a direct user role to the project and a (non-inherited) + user role to the domain + - Get a list of effective roles - should only get the one direct role + - Now add an inherited user role to the domain + - Get a list of effective roles - should have two roles, one + direct and one by virtue of the inherited user role + - Also get effective roles for the domain - the role marked as + inherited should not show up + + """ + self.opt_in_group('os_inherit', enabled=True) + role_list = [] + for _ in range(3): + role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.identity_api.create_role(role['id'], role) + role_list.append(role) + domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.identity_api.create_domain(domain1['id'], domain1) + user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, + 'domain_id': domain1['id'], 'password': uuid.uuid4().hex, + 'enabled': True} + self.identity_api.create_user(user1['id'], user1) + project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, + 'domain_id': domain1['id']} + self.identity_api.create_project(project1['id'], project1) + + roles_ref = self.identity_api.list_grants( + user_id=user1['id'], + project_id=project1['id']) + self.assertEquals(len(roles_ref), 0) + + # Create the first two roles - the domain one is not inherited + self.identity_api.create_grant(user_id=user1['id'], + project_id=project1['id'], + role_id=role_list[0]['id']) + self.identity_api.create_grant(user_id=user1['id'], + domain_id=domain1['id'], + role_id=role_list[1]['id']) + + # Now get the effective roles for the user and project, this + # should only include the direct role assignment on the project + combined_role_list = self.identity_api.get_roles_for_user_and_project( + user1['id'], project1['id']) + self.assertEquals(len(combined_role_list), 1) + self.assertIn(role_list[0]['id'], combined_role_list) + + # Now add an inherited role on the domain + self.identity_api.create_grant(user_id=user1['id'], + domain_id=domain1['id'], + role_id=role_list[2]['id'], + inherited_to_projects=True) + + # Now get the effective roles for the user and project again, this + # should now include the inherited role on the domain + combined_role_list = self.identity_api.get_roles_for_user_and_project( + user1['id'], project1['id']) + self.assertEquals(len(combined_role_list), 2) + self.assertIn(role_list[0]['id'], combined_role_list) + self.assertIn(role_list[2]['id'], combined_role_list) + + # Finally, check that the inherited role does not appear as a valid + # directly assigned role on the domain itself + combined_role_list = self.identity_api.get_roles_for_user_and_domain( + user1['id'], domain1['id']) + self.assertEquals(len(combined_role_list), 1) + self.assertIn(role_list[1]['id'], combined_role_list) + + def test_inherited_role_grants_for_group(self): + """Test inherited group roles. + + Test Plan: + - Enable OS-INHERIT extension + - Create 4 roles + - Create a domain, with a project, user and two groups + - Make the user a member of both groups + - Check no roles yet exit + - Assign a direct user role to the project and a (non-inherited) + group role on the domain + - Get a list of effective roles - should only get the one direct role + - Now add two inherited group roles to the domain + - Get a list of effective roles - should have three roles, one + direct and two by virtue of inherited group roles + + """ + self.opt_in_group('os_inherit', enabled=True) + role_list = [] + for _ in range(4): + role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.identity_api.create_role(role['id'], role) + role_list.append(role) + domain1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.identity_api.create_domain(domain1['id'], domain1) + user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, + 'domain_id': domain1['id'], 'password': uuid.uuid4().hex, + 'enabled': True} + self.identity_api.create_user(user1['id'], user1) + group1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, + 'domain_id': domain1['id'], 'enabled': True} + self.identity_api.create_group(group1['id'], group1) + group2 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, + 'domain_id': domain1['id'], 'enabled': True} + self.identity_api.create_group(group2['id'], group2) + project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, + 'domain_id': domain1['id']} + self.identity_api.create_project(project1['id'], project1) + + self.identity_api.add_user_to_group(user1['id'], + group1['id']) + self.identity_api.add_user_to_group(user1['id'], + group2['id']) + + roles_ref = self.identity_api.list_grants( + user_id=user1['id'], + project_id=project1['id']) + self.assertEquals(len(roles_ref), 0) + + # Create two roles - the domain one is not inherited + self.identity_api.create_grant(user_id=user1['id'], + project_id=project1['id'], + role_id=role_list[0]['id']) + self.identity_api.create_grant(group_id=group1['id'], + domain_id=domain1['id'], + role_id=role_list[1]['id']) + + # Now get the effective roles for the user and project, this + # should only include the direct role assignment on the project + combined_role_list = self.identity_api.get_roles_for_user_and_project( + user1['id'], project1['id']) + self.assertEquals(len(combined_role_list), 1) + self.assertIn(role_list[0]['id'], combined_role_list) + + # Now add to more group roles, both inherited, to the domain + self.identity_api.create_grant(group_id=group2['id'], + domain_id=domain1['id'], + role_id=role_list[2]['id'], + inherited_to_projects=True) + self.identity_api.create_grant(group_id=group2['id'], + domain_id=domain1['id'], + role_id=role_list[3]['id'], + inherited_to_projects=True) + + # Now get the effective roles for the user and project again, this + # should now include the inherited roles on the domain + combined_role_list = self.identity_api.get_roles_for_user_and_project( + user1['id'], project1['id']) + self.assertEquals(len(combined_role_list), 3) + self.assertIn(role_list[0]['id'], combined_role_list) + self.assertIn(role_list[2]['id'], combined_role_list) + self.assertIn(role_list[3]['id'], combined_role_list) diff --git a/tests/test_backend_kvs.py b/tests/test_backend_kvs.py index 0c6c2abe..d92a7510 100644 --- a/tests/test_backend_kvs.py +++ b/tests/test_backend_kvs.py @@ -15,8 +15,6 @@ # under the License. import uuid -import nose.exc - from keystone import test from keystone import exception @@ -36,34 +34,34 @@ class KvsIdentity(test.TestCase, test_backend.IdentityTests): def test_list_user_projects(self): # NOTE(chungg): not implemented - raise nose.exc.SkipTest('Blocked by bug 1119770') + self.skipTest('Blocked by bug 1119770') def test_create_duplicate_group_name_in_different_domains(self): - raise nose.exc.SkipTest('Blocked by bug 1119770') + self.skipTest('Blocked by bug 1119770') def test_create_duplicate_user_name_in_different_domains(self): - raise nose.exc.SkipTest('Blocked by bug 1119770') + self.skipTest('Blocked by bug 1119770') def test_create_duplicate_project_name_in_different_domains(self): - raise nose.exc.SkipTest('Blocked by bug 1119770') + self.skipTest('Blocked by bug 1119770') def test_move_user_between_domains(self): - raise nose.exc.SkipTest('Blocked by bug 1119770') + self.skipTest('Blocked by bug 1119770') def test_move_user_between_domains_with_clashing_names_fails(self): - raise nose.exc.SkipTest('Blocked by bug 1119770') + self.skipTest('Blocked by bug 1119770') def test_move_group_between_domains(self): - raise nose.exc.SkipTest('Blocked by bug 1119770') + self.skipTest('Blocked by bug 1119770') def test_move_group_between_domains_with_clashing_names_fails(self): - raise nose.exc.SkipTest('Blocked by bug 1119770') + self.skipTest('Blocked by bug 1119770') def test_move_project_between_domains(self): - raise nose.exc.SkipTest('Blocked by bug 1119770') + self.skipTest('Blocked by bug 1119770') def test_move_project_between_domains_with_clashing_names_fails(self): - raise nose.exc.SkipTest('Blocked by bug 1119770') + self.skipTest('Blocked by bug 1119770') class KvsToken(test.TestCase, test_backend.TokenTests): diff --git a/tests/test_backend_ldap.py b/tests/test_backend_ldap.py index 577a6ef0..ec2b2737 100644 --- a/tests/test_backend_ldap.py +++ b/tests/test_backend_ldap.py @@ -17,14 +17,13 @@ import uuid -import nose.exc - -from keystone import test - +from keystone import assignment from keystone.common.ldap import fakeldap +from keystone.common import sql from keystone import config from keystone import exception from keystone import identity +from keystone import test import default_fixtures import test_backend @@ -33,7 +32,7 @@ import test_backend CONF = config.CONF -class LDAPIdentity(test.TestCase, test_backend.IdentityTests): +class BaseLDAPIdentity(test_backend.IdentityTests): def _get_domain_fixture(self): """Domains in LDAP are read-only, so just return the static one.""" return self.identity_api.get_domain(CONF.identity.default_domain_id) @@ -47,14 +46,6 @@ class LDAPIdentity(test.TestCase, test_backend.IdentityTests): test.testsdir('test_overrides.conf'), test.testsdir('backend_ldap.conf')]) - def setUp(self): - super(LDAPIdentity, self).setUp() - self._set_config() - self.clear_database() - - self.load_backends() - self.load_fixtures(default_fixtures) - def test_build_tree(self): """Regression test for building the tree names """ @@ -104,6 +95,202 @@ class LDAPIdentity(test.TestCase, test_backend.IdentityTests): self.identity_api.delete_user, self.user_foo['id']) + def test_user_filter(self): + user_ref = self.identity_api.get_user(self.user_foo['id']) + self.user_foo.pop('password') + self.assertDictEqual(user_ref, self.user_foo) + + CONF.ldap.user_filter = '(CN=DOES_NOT_MATCH)' + self.load_backends() + self.assertRaises(exception.UserNotFound, + self.identity_api.get_user, + self.user_foo['id']) + + def test_get_role_grant_by_user_and_project(self): + self.skipTest('Blocked by bug 1101287') + + def test_get_role_grants_for_user_and_project_404(self): + self.skipTest('Blocked by bug 1101287') + + def test_add_role_grant_to_user_and_project_404(self): + self.skipTest('Blocked by bug 1101287') + + def test_remove_role_grant_from_user_and_project(self): + self.skipTest('Blocked by bug 1101287') + + def test_get_and_remove_role_grant_by_group_and_project(self): + self.skipTest('Blocked by bug 1101287') + + def test_get_and_remove_role_grant_by_group_and_domain(self): + self.skipTest('N/A: LDAP does not support multiple domains') + + def test_get_and_remove_role_grant_by_user_and_domain(self): + self.skipTest('N/A: LDAP does not support multiple domains') + + def test_get_and_remove_correct_role_grant_from_a_mix(self): + self.skipTest('Blocked by bug 1101287') + + def test_get_and_remove_role_grant_by_group_and_cross_domain(self): + self.skipTest('N/A: LDAP does not support multiple domains') + + def test_get_and_remove_role_grant_by_user_and_cross_domain(self): + self.skipTest('N/A: LDAP does not support multiple domains') + + def test_role_grant_by_group_and_cross_domain_project(self): + self.skipTest('N/A: LDAP does not support multiple domains') + + def test_role_grant_by_user_and_cross_domain_project(self): + self.skipTest('N/A: LDAP does not support multiple domains') + + def test_multi_role_grant_by_user_group_on_project_domain(self): + self.skipTest('N/A: LDAP does not support multiple domains') + + def test_delete_role_with_user_and_group_grants(self): + self.skipTest('Blocked by bug 1101287') + + def test_delete_user_with_group_project_domain_links(self): + self.skipTest('N/A: LDAP does not support multiple domains') + + def test_delete_group_with_user_project_domain_links(self): + self.skipTest('N/A: LDAP does not support multiple domains') + + def test_list_user_projects(self): + self.skipTest('Blocked by bug 1101287') + + def test_create_duplicate_user_name_in_different_domains(self): + self.skipTest('Blocked by bug 1101276') + + def test_create_duplicate_project_name_in_different_domains(self): + self.skipTest('Blocked by bug 1101276') + + def test_create_duplicate_group_name_in_different_domains(self): + self.skipTest( + 'N/A: LDAP does not support multiple domains') + + def test_move_user_between_domains(self): + self.skipTest('Blocked by bug 1101276') + + def test_move_user_between_domains_with_clashing_names_fails(self): + self.skipTest('Blocked by bug 1101276') + + def test_move_group_between_domains(self): + self.skipTest( + 'N/A: LDAP does not support multiple domains') + + def test_move_group_between_domains_with_clashing_names_fails(self): + self.skipTest('Blocked by bug 1101276') + + def test_move_project_between_domains(self): + self.skipTest('Blocked by bug 1101276') + + def test_move_project_between_domains_with_clashing_names_fails(self): + self.skipTest('Blocked by bug 1101276') + + def test_get_roles_for_user_and_domain(self): + self.skipTest('N/A: LDAP does not support multiple domains') + + def test_list_role_assignments_unfiltered(self): + self.skipTest('Blocked by bug 1195019') + + def test_multi_group_grants_on_project_domain(self): + self.skipTest('Blocked by bug 1101287') + + def test_list_group_members_missing_entry(self): + """List group members with deleted user. + + If a group has a deleted entry for a member, the non-deleted members + are returned. + + """ + + # Create a group + group_id = None + group = dict(name=uuid.uuid4().hex) + group_id = self.identity_api.create_group(group_id, group)['id'] + + # Create a couple of users and add them to the group. + user_id = None + user = dict(name=uuid.uuid4().hex, id=uuid.uuid4().hex) + user_1_id = self.identity_api.create_user(user_id, user)['id'] + + self.identity_api.add_user_to_group(user_1_id, group_id) + + user_id = None + user = dict(name=uuid.uuid4().hex, id=uuid.uuid4().hex) + user_2_id = self.identity_api.create_user(user_id, user)['id'] + + self.identity_api.add_user_to_group(user_2_id, group_id) + + # Delete user 2 + # NOTE(blk-u): need to go directly to user interface to keep from + # updating the group. + self.identity_api.driver.user.delete(user_2_id) + + # List group users and verify only user 1. + res = self.identity_api.list_users_in_group(group_id) + + self.assertEqual(len(res), 1, "Expected 1 entry (user_1)") + self.assertEqual(res[0]['id'], user_1_id, "Expected user 1 id") + + def test_list_domains(self): + domains = self.identity_api.list_domains() + self.assertEquals( + domains, + [assignment.DEFAULT_DOMAIN]) + + def test_authenticate_requires_simple_bind(self): + user = { + 'id': 'no_meta', + 'name': 'NO_META', + 'domain_id': test_backend.DEFAULT_DOMAIN_ID, + 'password': 'no_meta2', + 'enabled': True, + } + self.identity_api.create_user(user['id'], user) + self.identity_api.add_user_to_project(self.tenant_baz['id'], + user['id']) + self.identity_api.driver.user.LDAP_USER = None + self.identity_api.driver.user.LDAP_PASSWORD = None + + self.assertRaises(AssertionError, + self.identity_api.authenticate, + user_id=user['id'], + password=None) + + # (spzala)The group and domain crud tests below override the standard ones + # in test_backend.py so that we can exclude the update name test, since we + # do not yet support the update of either group or domain names with LDAP. + # In the tests below, the update is demonstrated by updating description. + # Refer to bug 1136403 for more detail. + def test_group_crud(self): + group = { + 'id': uuid.uuid4().hex, + 'domain_id': CONF.identity.default_domain_id, + 'name': uuid.uuid4().hex, + 'description': uuid.uuid4().hex} + self.identity_api.create_group(group['id'], group) + group_ref = self.identity_api.get_group(group['id']) + self.assertDictEqual(group_ref, group) + group['description'] = uuid.uuid4().hex + self.identity_api.update_group(group['id'], group) + group_ref = self.identity_api.get_group(group['id']) + self.assertDictEqual(group_ref, group) + + self.identity_api.delete_group(group['id']) + self.assertRaises(exception.GroupNotFound, + self.identity_api.get_group, + group['id']) + + +class LDAPIdentity(test.TestCase, BaseLDAPIdentity): + def setUp(self): + super(LDAPIdentity, self).setUp() + self._set_config() + self.clear_database() + + self.load_backends() + self.load_fixtures(default_fixtures) + def test_configurable_allowed_project_actions(self): tenant = {'id': 'fake1', 'name': 'fake1', 'enabled': True} self.identity_api.create_project('fake1', tenant) @@ -175,17 +362,6 @@ class LDAPIdentity(test.TestCase, test_backend.IdentityTests): self.identity_api.delete_role, self.role_member['id']) - def test_user_filter(self): - user_ref = self.identity_api.get_user(self.user_foo['id']) - self.user_foo.pop('password') - self.assertDictEqual(user_ref, self.user_foo) - - CONF.ldap.user_filter = '(CN=DOES_NOT_MATCH)' - self.load_backends() - self.assertRaises(exception.UserNotFound, - self.identity_api.get_user, - self.user_foo['id']) - def test_project_filter(self): tenant_ref = self.identity_api.get_project(self.tenant_bar['id']) self.assertDictEqual(tenant_ref, self.tenant_bar) @@ -216,40 +392,6 @@ class LDAPIdentity(test.TestCase, test_backend.IdentityTests): self.identity_api.get_user, 'dumb') - def test_user_attribute_mapping(self): - CONF.ldap.user_name_attribute = 'sn' - CONF.ldap.user_mail_attribute = 'mail' - CONF.ldap.user_enabled_attribute = 'enabled' - self.clear_database() - self.load_backends() - self.load_fixtures(default_fixtures) - user_ref = self.identity_api.get_user(self.user_two['id']) - self.assertEqual(user_ref['id'], self.user_two['id']) - self.assertEqual(user_ref['name'], self.user_two['name']) - self.assertEqual(user_ref['email'], self.user_two['email']) - - CONF.ldap.user_name_attribute = 'mail' - CONF.ldap.user_mail_attribute = 'sn' - self.load_backends() - user_ref = self.identity_api.get_user(self.user_two['id']) - self.assertEqual(user_ref['id'], self.user_two['id']) - self.assertEqual(user_ref['name'], self.user_two['email']) - self.assertEqual(user_ref['email'], self.user_two['name']) - - def test_user_attribute_ignore(self): - CONF.ldap.user_attribute_ignore = ['email', 'password', - 'tenant_id', 'enabled', 'tenants'] - self.clear_database() - self.load_backends() - self.load_fixtures(default_fixtures) - user_ref = self.identity_api.get_user(self.user_two['id']) - self.assertEqual(user_ref['id'], self.user_two['id']) - self.assertNotIn('email', user_ref) - self.assertNotIn('password', user_ref) - self.assertNotIn('tenant_id', user_ref) - self.assertNotIn('enabled', user_ref) - self.assertNotIn('tenants', user_ref) - def test_project_attribute_mapping(self): CONF.ldap.tenant_name_attribute = 'ou' CONF.ldap.tenant_desc_attribute = 'description' @@ -384,30 +526,6 @@ class LDAPIdentity(test.TestCase, test_backend.IdentityTests): # TODO(henry-nash): These need to be removed when the full LDAP implementation # is submitted - see Bugs 1092187, 1101287, 1101276, 1101289 - # (spzala)The group and domain crud tests below override the standard ones - # in test_backend.py so that we can exclude the update name test, since we - # do not yet support the update of either group or domain names with LDAP. - # In the tests below, the update is demonstrated by updating description. - # Refer to bug 1136403 for more detail. - def test_group_crud(self): - group = { - 'id': uuid.uuid4().hex, - 'domain_id': CONF.identity.default_domain_id, - 'name': uuid.uuid4().hex, - 'description': uuid.uuid4().hex} - self.identity_api.create_group(group['id'], group) - group_ref = self.identity_api.get_group(group['id']) - self.assertDictEqual(group_ref, group) - group['description'] = uuid.uuid4().hex - self.identity_api.update_group(group['id'], group) - group_ref = self.identity_api.get_group(group['id']) - self.assertDictEqual(group_ref, group) - - self.identity_api.delete_group(group['id']) - self.assertRaises(exception.GroupNotFound, - self.identity_api.get_group, - group['id']) - def test_domain_crud(self): domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, 'enabled': True, 'description': uuid.uuid4().hex} @@ -434,30 +552,6 @@ class LDAPIdentity(test.TestCase, test_backend.IdentityTests): self.identity_api.get_domain, domain['id']) - def test_get_role_grant_by_user_and_project(self): - raise nose.exc.SkipTest('Blocked by bug 1101287') - - def test_get_role_grants_for_user_and_project_404(self): - raise nose.exc.SkipTest('Blocked by bug 1101287') - - def test_add_role_grant_to_user_and_project_404(self): - raise nose.exc.SkipTest('Blocked by bug 1101287') - - def test_remove_role_grant_from_user_and_project(self): - raise nose.exc.SkipTest('Blocked by bug 1101287') - - def test_get_and_remove_role_grant_by_group_and_project(self): - raise nose.exc.SkipTest('Blocked by bug 1101287') - - def test_get_and_remove_role_grant_by_group_and_domain(self): - raise nose.exc.SkipTest('N/A: LDAP does not support multiple domains') - - def test_get_and_remove_role_grant_by_user_and_domain(self): - raise nose.exc.SkipTest('N/A: LDAP does not support multiple domains') - - def test_get_and_remove_correct_role_grant_from_a_mix(self): - raise nose.exc.SkipTest('Blocked by bug 1101287') - def test_project_crud(self): # NOTE(topol): LDAP implementation does not currently support the # updating of a project name so this method override @@ -466,12 +560,12 @@ class LDAPIdentity(test.TestCase, test_backend.IdentityTests): 'domain_id': CONF.identity.default_domain_id, 'description': uuid.uuid4().hex } - self.identity_api.driver.create_project(project['id'], project) - project_ref = self.identity_api.driver.get_project(project['id']) + self.assignment_api.create_project(project['id'], project) + project_ref = self.assignment_api.get_project(project['id']) # NOTE(crazed): If running live test with emulation, there will be # an enabled key in the project_ref. - if self.identity_api.driver.project.enabled_emulation: + if self.assignment_api.driver.project.enabled_emulation: project['enabled'] = True self.assertDictEqual(project_ref, project) @@ -485,129 +579,59 @@ class LDAPIdentity(test.TestCase, test_backend.IdentityTests): self.identity_api.get_project, project['id']) - def test_get_and_remove_role_grant_by_group_and_cross_domain(self): - raise nose.exc.SkipTest('N/A: LDAP does not support multiple domains') - - def test_get_and_remove_role_grant_by_user_and_cross_domain(self): - raise nose.exc.SkipTest('N/A: LDAP does not support multiple domains') - - def test_role_grant_by_group_and_cross_domain_project(self): - raise nose.exc.SkipTest('N/A: LDAP does not support multiple domains') - - def test_role_grant_by_user_and_cross_domain_project(self): - raise nose.exc.SkipTest('N/A: LDAP does not support multiple domains') - def test_multi_role_grant_by_user_group_on_project_domain(self): - raise nose.exc.SkipTest('N/A: LDAP does not support multiple domains') - - def test_delete_role_with_user_and_group_grants(self): - raise nose.exc.SkipTest('Blocked by bug 1101287') - - def test_delete_user_with_group_project_domain_links(self): - raise nose.exc.SkipTest('N/A: LDAP does not support multiple domains') - - def test_delete_group_with_user_project_domain_links(self): - raise nose.exc.SkipTest('N/A: LDAP does not support multiple domains') - - def test_list_user_projects(self): - raise nose.exc.SkipTest('Blocked by bug 1101287') - - def test_create_duplicate_user_name_in_different_domains(self): - raise nose.exc.SkipTest('Blocked by bug 1101276') - - def test_create_duplicate_project_name_in_different_domains(self): - raise nose.exc.SkipTest('Blocked by bug 1101276') - - def test_create_duplicate_group_name_in_different_domains(self): - raise nose.exc.SkipTest( - 'N/A: LDAP does not support multiple domains') - - def test_move_user_between_domains(self): - raise nose.exc.SkipTest('Blocked by bug 1101276') - - def test_move_user_between_domains_with_clashing_names_fails(self): - raise nose.exc.SkipTest('Blocked by bug 1101276') - - def test_move_group_between_domains(self): - raise nose.exc.SkipTest( + # This is a partial implementation of the standard test that + # is defined in test_backend.py. It omits both domain and + # group grants. since neither of these are yet supported by + # the ldap backend. + + role_list = [] + for _ in range(2): + role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.identity_api.create_role(role['id'], role) + role_list.append(role) + + user1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, + 'domain_id': CONF.identity.default_domain_id, + 'password': uuid.uuid4().hex, + 'enabled': True} + self.identity_api.create_user(user1['id'], user1) + project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, + 'domain_id': CONF.identity.default_domain_id} + self.identity_api.create_project(project1['id'], project1) + + self.identity_api.add_role_to_user_and_project( + user_id=user1['id'], + tenant_id=project1['id'], + role_id=role_list[0]['id']) + self.identity_api.add_role_to_user_and_project( + user_id=user1['id'], + tenant_id=project1['id'], + role_id=role_list[1]['id']) + + # Although list_grants are not yet supported, we can test the + # alternate way of getting back lists of grants, where user + # and group roles are combined. Only directly assigned user + # roles are available, since group grants are not yet supported + + combined_role_list = self.identity_api.get_roles_for_user_and_project( + user1['id'], project1['id']) + self.assertEquals(len(combined_role_list), 2) + self.assertIn(role_list[0]['id'], combined_role_list) + self.assertIn(role_list[1]['id'], combined_role_list) + + # Finally, although domain roles are not implemented, check we can + # issue the combined get roles call with benign results, since thus is + # used in token generation + + combined_role_list = self.identity_api.get_roles_for_user_and_domain( + user1['id'], CONF.identity.default_domain_id) + self.assertEquals(len(combined_role_list), 0) + + def test_list_projects_for_alternate_domain(self): + self.skipTest( 'N/A: LDAP does not support multiple domains') - def test_move_group_between_domains_with_clashing_names_fails(self): - raise nose.exc.SkipTest('Blocked by bug 1101276') - - def test_move_project_between_domains(self): - raise nose.exc.SkipTest('Blocked by bug 1101276') - - def test_move_project_between_domains_with_clashing_names_fails(self): - raise nose.exc.SkipTest('Blocked by bug 1101276') - - def test_get_roles_for_user_and_domain(self): - raise nose.exc.SkipTest('N/A: LDAP does not support multiple domains') - - def test_list_group_members_missing_entry(self): - """List group members with deleted user. - - If a group has a deleted entry for a member, the non-deleted members - are returned. - - """ - - # Create a group - group_id = None - group = dict(name=uuid.uuid4().hex) - group_id = self.identity_api.create_group(group_id, group)['id'] - - # Create a couple of users and add them to the group. - user_id = None - user = dict(name=uuid.uuid4().hex, id=uuid.uuid4().hex) - user_1_id = self.identity_api.create_user(user_id, user)['id'] - - self.identity_api.add_user_to_group(user_1_id, group_id) - - user_id = None - user = dict(name=uuid.uuid4().hex, id=uuid.uuid4().hex) - user_2_id = self.identity_api.create_user(user_id, user)['id'] - - self.identity_api.add_user_to_group(user_2_id, group_id) - - # Delete user 2 - # NOTE(blk-u): need to go directly to user interface to keep from - # updating the group. - self.identity_api.driver.user.delete(user_2_id) - - # List group users and verify only user 1. - res = self.identity_api.list_users_in_group(group_id) - - self.assertEqual(len(res), 1, "Expected 1 entry (user_1)") - self.assertEqual(res[0]['id'], user_1_id, "Expected user 1 id") - - def test_list_domains(self): - domains = self.identity_api.list_domains() - self.assertEquals( - domains, - [{'id': CONF.identity.default_domain_id, - 'name': 'Default', - 'enabled': True}]) - - def test_authenticate_requires_simple_bind(self): - user = { - 'id': 'no_meta', - 'name': 'NO_META', - 'domain_id': test_backend.DEFAULT_DOMAIN_ID, - 'password': 'no_meta2', - 'enabled': True, - } - self.identity_api.create_user(user['id'], user) - self.identity_api.add_user_to_project(self.tenant_baz['id'], - user['id']) - self.identity_api.driver.user.LDAP_USER = None - self.identity_api.driver.user.LDAP_PASSWORD = None - - self.assertRaises(AssertionError, - self.identity_api.authenticate_user, - user_id=user['id'], - password=None) - class LDAPIdentityEnabledEmulation(LDAPIdentity): def setUp(self): @@ -624,30 +648,6 @@ class LDAPIdentityEnabledEmulation(LDAPIdentity): self.user_two, self.user_badguy]: obj.setdefault('enabled', True) - def test_authenticate_no_metadata(self): - user = { - 'id': 'no_meta', - 'name': 'NO_META', - 'domain_id': test_backend.DEFAULT_DOMAIN_ID, - 'password': 'no_meta2', - 'enabled': True, - } - self.identity_api.create_user(user['id'], user) - self.identity_api.add_user_to_project(self.tenant_baz['id'], - user['id']) - user_ref, tenant_ref, metadata_ref = self.identity_api.authenticate( - user_id=user['id'], - tenant_id=self.tenant_baz['id'], - password=user['password']) - # NOTE(termie): the password field is left in user_foo to make - # it easier to authenticate in tests, but should - # not be returned by the api - user.pop('password') - self.assertEquals(metadata_ref, {"roles": - [CONF.member_role_id]}) - self.assertDictEqual(user_ref, user) - self.assertDictEqual(tenant_ref, self.tenant_baz) - def test_project_crud(self): # NOTE(topol): LDAPIdentityEnabledEmulation will create an # enabled key in the project dictionary so this @@ -703,5 +703,43 @@ class LDAPIdentityEnabledEmulation(LDAPIdentity): user['id']) def test_user_enable_attribute_mask(self): - raise nose.exc.SkipTest( + self.skipTest( "Enabled emulation conflicts with enabled mask") + + +class LdapIdentitySqlAssignment(sql.Base, test.TestCase, BaseLDAPIdentity): + + def _set_config(self): + self.config([test.etcdir('keystone.conf.sample'), + test.testsdir('test_overrides.conf'), + test.testsdir('backend_ldap_sql.conf')]) + + def setUp(self): + self._set_config() + self.clear_database() + self.load_backends() + self.engine = self.get_engine() + sql.ModelBase.metadata.create_all(bind=self.engine) + self.load_fixtures(default_fixtures) + #defaulted by the data load + self.user_foo['enabled'] = True + + def tearDown(self): + sql.ModelBase.metadata.drop_all(bind=self.engine) + self.engine.dispose() + sql.set_global_engine(None) + + def test_domain_crud(self): + pass + + def test_list_domains(self): + domains = self.identity_api.list_domains() + self.assertEquals(domains, [assignment.DEFAULT_DOMAIN]) + + def test_project_filter(self): + self.skipTest( + 'N/A: Not part of SQL backend') + + def test_role_filter(self): + self.skipTest( + 'N/A: Not part of SQL backend') diff --git a/tests/test_backend_memcache.py b/tests/test_backend_memcache.py index 66401e09..7516e0dd 100644 --- a/tests/test_backend_memcache.py +++ b/tests/test_backend_memcache.py @@ -164,7 +164,7 @@ class MemcacheToken(test.TestCase, test_backend.TokenTests): user_token_list = jsonutils.loads('[%s]' % user_record) self.assertEquals(len(user_token_list), 2) expired_token_ptk = self.token_api.driver._prefix_token_id( - token.unique_id(expired_token_id)) + expired_token_id) expired_token = self.token_api.driver.client.get(expired_token_ptk) expired_token['expires'] = (timeutils.utcnow() - expire_delta) self.token_api.driver.client.set(expired_token_ptk, expired_token) diff --git a/tests/test_backend_pam.py b/tests/test_backend_pam.py index 3a66f014..b66faa9c 100644 --- a/tests/test_backend_pam.py +++ b/tests/test_backend_pam.py @@ -57,12 +57,12 @@ class PamIdentity(test.TestCase): self.assertDictEqual(self.user_in, user_out) def test_get_metadata_for_non_root(self): - metadata_out = self.identity_api.get_metadata(self.user_in['id'], - self.tenant_in['id']) + metadata_out = self.identity_api._get_metadata(self.user_in['id'], + self.tenant_in['id']) self.assertDictEqual({}, metadata_out) def test_get_metadata_for_root(self): metadata = {'is_admin': True} - metadata_out = self.identity_api.get_metadata('root', - self.tenant_in['id']) + metadata_out = self.identity_api._get_metadata('root', + self.tenant_in['id']) self.assertDictEqual(metadata, metadata_out) diff --git a/tests/test_backend_sql.py b/tests/test_backend_sql.py index 46d7c013..89276e86 100644 --- a/tests/test_backend_sql.py +++ b/tests/test_backend_sql.py @@ -16,6 +16,8 @@ import uuid +import sqlalchemy + from keystone import test from keystone.common import sql @@ -57,6 +59,94 @@ class SqlTests(test.TestCase, sql.Base): super(SqlTests, self).tearDown() +class SqlModels(SqlTests): + def setUp(self): + super(SqlModels, self).setUp() + + self.metadata = sql.ModelBase.metadata + self.metadata.bind = self.engine + + def select_table(self, name): + table = sqlalchemy.Table(name, + self.metadata, + autoload=True) + s = sqlalchemy.select([table]) + return s + + def assertExpectedSchema(self, table, cols): + table = self.select_table(table) + for col, type_, length in cols: + self.assertIsInstance(table.c[col].type, type_) + if length: + self.assertEquals(table.c[col].type.length, length) + + def test_user_model(self): + cols = (('id', sql.String, 64), + ('name', sql.String, 64), + ('password', sql.String, 128), + ('domain_id', sql.String, 64), + ('enabled', sql.Boolean, None), + ('extra', sql.JsonBlob, None)) + self.assertExpectedSchema('user', cols) + + def test_group_model(self): + cols = (('id', sql.String, 64), + ('name', sql.String, 64), + ('description', sql.Text, None), + ('domain_id', sql.String, 64), + ('extra', sql.JsonBlob, None)) + self.assertExpectedSchema('group', cols) + + def test_domain_model(self): + cols = (('id', sql.String, 64), + ('name', sql.String, 64), + ('enabled', sql.Boolean, None)) + self.assertExpectedSchema('domain', cols) + + def test_project_model(self): + cols = (('id', sql.String, 64), + ('name', sql.String, 64), + ('description', sql.Text, None), + ('domain_id', sql.String, 64), + ('enabled', sql.Boolean, None), + ('extra', sql.JsonBlob, None)) + self.assertExpectedSchema('project', cols) + + def test_role_model(self): + cols = (('id', sql.String, 64), + ('name', sql.String, 255)) + self.assertExpectedSchema('role', cols) + + def test_user_project_metadata_model(self): + cols = (('user_id', sql.String, 64), + ('project_id', sql.String, 64), + ('data', sql.JsonBlob, None)) + self.assertExpectedSchema('user_project_metadata', cols) + + def test_user_domain_metadata_model(self): + cols = (('user_id', sql.String, 64), + ('domain_id', sql.String, 64), + ('data', sql.JsonBlob, None)) + self.assertExpectedSchema('user_domain_metadata', cols) + + def test_group_project_metadata_model(self): + cols = (('group_id', sql.String, 64), + ('project_id', sql.String, 64), + ('data', sql.JsonBlob, None)) + self.assertExpectedSchema('group_project_metadata', cols) + + def test_group_domain_metadata_model(self): + cols = (('group_id', sql.String, 64), + ('domain_id', sql.String, 64), + ('data', sql.JsonBlob, None)) + self.assertExpectedSchema('group_domain_metadata', cols) + + def test_user_group_membership(self): + cols = (('group_id', sql.String, 64), + ('user_id', sql.String, 64)) + self.assertExpectedSchema('user_group_membership', cols) + + class SqlIdentity(SqlTests, test_backend.IdentityTests): def test_password_hashed(self): session = self.identity_api.get_session() @@ -132,33 +222,51 @@ class SqlIdentity(SqlTests, test_backend.IdentityTests): tenants = self.identity_api.get_projects_for_user(user['id']) self.assertEquals(tenants, []) - def test_delete_user_with_metadata(self): - user = {'id': 'fake', - 'name': 'fakeuser', + def test_metadata_removed_on_delete_user(self): + # A test to check that the internal representation + # or roles is correctly updated when a user is deleted + user = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex, 'domain_id': DEFAULT_DOMAIN_ID, 'password': 'passwd'} - self.identity_api.create_user('fake', user) - self.identity_api.create_metadata(user['id'], - self.tenant_bar['id'], - {'extra': 'extra'}) + self.identity_api.create_user(user['id'], user) + role = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex} + self.identity_api.create_role(role['id'], role) + self.identity_api.add_role_to_user_and_project( + user['id'], + self.tenant_bar['id'], + role['id']) self.identity_api.delete_user(user['id']) + + # Now check whether the internal representation of roles + # has been deleted self.assertRaises(exception.MetadataNotFound, - self.identity_api.get_metadata, + self.assignment_api._get_metadata, user['id'], self.tenant_bar['id']) - def test_delete_project_with_metadata(self): - user = {'id': 'fake', - 'name': 'fakeuser', + def test_metadata_removed_on_delete_project(self): + # A test to check that the internal representation + # or roles is correctly updated when a project is deleted + user = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex, 'domain_id': DEFAULT_DOMAIN_ID, 'password': 'passwd'} - self.identity_api.create_user('fake', user) - self.identity_api.create_metadata(user['id'], - self.tenant_bar['id'], - {'extra': 'extra'}) + self.identity_api.create_user(user['id'], user) + role = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex} + self.identity_api.create_role(role['id'], role) + self.identity_api.add_role_to_user_and_project( + user['id'], + self.tenant_bar['id'], + role['id']) self.identity_api.delete_project(self.tenant_bar['id']) + + # Now check whether the internal representation of roles + # has been deleted self.assertRaises(exception.MetadataNotFound, - self.identity_api.get_metadata, + self.assignment_api._get_metadata, user['id'], self.tenant_bar['id']) @@ -302,3 +410,7 @@ class SqlCatalog(SqlTests, test_backend.CatalogTests): class SqlPolicy(SqlTests, test_backend.PolicyTests): pass + + +class SqlInheritance(SqlTests, test_backend.InheritanceTests): + pass diff --git a/tests/test_cert_setup.py b/tests/test_cert_setup.py index 74e5466a..e6c395e9 100644 --- a/tests/test_cert_setup.py +++ b/tests/test_cert_setup.py @@ -61,7 +61,6 @@ class CertSetupTestCase(test.TestCase): self.controller = token.controllers.Auth() def test_can_handle_missing_certs(self): - self.opt_in_group('signing', token_format='PKI') self.opt_in_group('signing', certfile='invalid') user = { 'id': 'fake1', diff --git a/tests/test_content_types.py b/tests/test_content_types.py index 820dc0dd..ebb5dcef 100644 --- a/tests/test_content_types.py +++ b/tests/test_content_types.py @@ -18,11 +18,11 @@ import io import uuid from lxml import etree -import nose.exc import webtest from keystone import test +from keystone.common import extension from keystone.common import serializer from keystone.openstack.common import jsonutils @@ -70,14 +70,12 @@ class RestfulTestCase(test.TestCase): self.admin_app = webtest.TestApp( self.loadapp('keystone', name='admin')) - # TODO(termie): is_admin is being deprecated once the policy stuff - # is all working # TODO(termie): add an admin user to the fixtures and use that user # override the fixtures, for now - self.metadata_foobar = self.identity_api.update_metadata( + self.metadata_foobar = self.identity_api.add_role_to_user_and_project( self.user_foo['id'], self.tenant_bar['id'], - dict(roles=[self.role_admin['id']], is_admin='1')) + self.role_admin['id']) def tearDown(self): """Kill running servers and release references to avoid leaks.""" @@ -336,14 +334,14 @@ class CoreApiTests(object): self.assertValidVersionResponse(r) def test_public_extensions(self): - self.public_request(path='/v2.0/extensions',) - - # TODO(dolph): can't test this without any public extensions defined - # self.assertValidExtensionListResponse(r) + r = self.public_request(path='/v2.0/extensions') + self.assertValidExtensionListResponse(r, + extension.PUBLIC_EXTENSIONS) def test_admin_extensions(self): - r = self.admin_request(path='/v2.0/extensions',) - self.assertValidExtensionListResponse(r) + r = self.admin_request(path='/v2.0/extensions') + self.assertValidExtensionListResponse(r, + extension.ADMIN_EXTENSIONS) def test_admin_extensions_404(self): self.admin_request(path='/v2.0/extensions/invalid-extension', @@ -355,7 +353,8 @@ class CoreApiTests(object): def test_admin_osksadm_extension(self): r = self.admin_request(path='/v2.0/extensions/OS-KSADM') - self.assertValidExtensionResponse(r) + self.assertValidExtensionResponse(r, + extension.ADMIN_EXTENSIONS) def test_authenticate(self): r = self.public_request( @@ -403,10 +402,10 @@ class CoreApiTests(object): self.assertValidAuthenticationResponse(r) def test_validate_token_service_role(self): - self.metadata_foobar = self.identity_api.update_metadata( + self.metadata_foobar = self.identity_api.add_role_to_user_and_project( self.user_foo['id'], self.tenant_service['id'], - dict(roles=[self.role_service['id']])) + self.role_service['id']) token = self.get_scoped_token(tenant_id='service') r = self.admin_request( @@ -471,7 +470,7 @@ class CoreApiTests(object): self.assertValidTenantResponse(r) def test_get_user_roles(self): - raise nose.exc.SkipTest('Blocked by bug 933565') + self.skipTest('Blocked by bug 933565') token = self.get_scoped_token() r = self.admin_request( @@ -613,24 +612,26 @@ class JsonTestCase(RestfulTestCase, CoreApiTests): self.assertValidError(r.result['error']) self.assertEqual(r.result['error']['code'], r.status_code) - def assertValidExtension(self, extension): + def assertValidExtension(self, extension, expected): super(JsonTestCase, self).assertValidExtension(extension) - - self.assertIsNotNone(extension.get('description')) + descriptions = [ext['description'] for ext in expected.itervalues()] + description = extension.get('description') + self.assertIsNotNone(description) + self.assertIn(description, descriptions) self.assertIsNotNone(extension.get('links')) self.assertNotEmpty(extension.get('links')) for link in extension.get('links'): self.assertValidExtensionLink(link) - def assertValidExtensionListResponse(self, r): + def assertValidExtensionListResponse(self, r, expected): self.assertIsNotNone(r.result.get('extensions')) self.assertIsNotNone(r.result['extensions'].get('values')) self.assertNotEmpty(r.result['extensions'].get('values')) for extension in r.result['extensions']['values']: - self.assertValidExtension(extension) + self.assertValidExtension(extension, expected) - def assertValidExtensionResponse(self, r): - self.assertValidExtension(r.result.get('extension')) + def assertValidExtensionResponse(self, r, expected): + self.assertValidExtension(r.result.get('extension'), expected) def assertValidAuthenticationResponse(self, r, require_service_catalog=False): @@ -852,29 +853,31 @@ class XmlTestCase(RestfulTestCase, CoreApiTests): self.assertValidError(xml) self.assertEqual(xml.get('code'), str(r.status_code)) - def assertValidExtension(self, extension): + def assertValidExtension(self, extension, expected): super(XmlTestCase, self).assertValidExtension(extension) self.assertIsNotNone(extension.find(self._tag('description'))) self.assertTrue(extension.find(self._tag('description')).text) links = extension.find(self._tag('links')) self.assertNotEmpty(links.findall(self._tag('link'))) + descriptions = [ext['description'] for ext in expected.itervalues()] + description = extension.find(self._tag('description')).text + self.assertIn(description, descriptions) for link in links.findall(self._tag('link')): self.assertValidExtensionLink(link) - def assertValidExtensionListResponse(self, r): + def assertValidExtensionListResponse(self, r, expected): xml = r.result self.assertEqual(xml.tag, self._tag('extensions')) - self.assertNotEmpty(xml.findall(self._tag('extension'))) - for extension in xml.findall(self._tag('extension')): - self.assertValidExtension(extension) + for ext in xml.findall(self._tag('extension')): + self.assertValidExtension(ext, expected) - def assertValidExtensionResponse(self, r): + def assertValidExtensionResponse(self, r, expected): xml = r.result self.assertEqual(xml.tag, self._tag('extension')) - self.assertValidExtension(xml) + self.assertValidExtension(xml, expected) def assertValidVersion(self, version): super(XmlTestCase, self).assertValidVersion(version) diff --git a/tests/test_drivers.py b/tests/test_drivers.py index 439b0d30..c83c1a89 100644 --- a/tests/test_drivers.py +++ b/tests/test_drivers.py @@ -1,6 +1,7 @@ import inspect import unittest2 as unittest +from keystone import assignment from keystone import catalog from keystone import exception from keystone import identity @@ -35,6 +36,10 @@ class TestDrivers(unittest.TestCase): if name[0] != '_' and callable(method): self.assertMethodNotImplemented(method) + def test_assignment_driver_unimplemented(self): + interface = assignment.Driver() + self.assertInterfaceNotImplemented(interface) + def test_catalog_driver_unimplemented(self): interface = catalog.Driver() self.assertInterfaceNotImplemented(interface) diff --git a/tests/test_exception.py b/tests/test_exception.py index ef06f633..d442d572 100644 --- a/tests/test_exception.py +++ b/tests/test_exception.py @@ -67,14 +67,14 @@ class ExceptionTestCase(test.TestCase): attribute = uuid.uuid4().hex e = exception.ValidationError(target=target, attribute=attribute) self.assertValidJsonRendering(e) - self.assertIn(target, str(e)) - self.assertIn(attribute, str(e)) + self.assertIn(target, unicode(e)) + self.assertIn(attribute, unicode(e)) def test_not_found(self): target = uuid.uuid4().hex e = exception.NotFound(target=target) self.assertValidJsonRendering(e) - self.assertIn(target, str(e)) + self.assertIn(target, unicode(e)) def test_403_title(self): e = exception.Forbidden() @@ -83,6 +83,15 @@ class ExceptionTestCase(test.TestCase): self.assertEqual('Forbidden', e.title) self.assertEqual('Forbidden', j['error'].get('title')) + def test_unicode_message(self): + message = u'Comment \xe7a va' + e = exception.Error(message) + + try: + self.assertEqual(unicode(e), message) + except UnicodeEncodeError: + self.fail("unicode error message not supported") + class SecurityErrorTestCase(ExceptionTestCase): """Tests whether security-related info is exposed to the API user.""" @@ -92,7 +101,7 @@ class SecurityErrorTestCase(ExceptionTestCase): risky_info = uuid.uuid4().hex e = exception.Unauthorized(message=risky_info) self.assertValidJsonRendering(e) - self.assertNotIn(risky_info, str(e)) + self.assertNotIn(risky_info, unicode(e)) def test_unauthorized_exposure_in_debug(self): self.opt(debug=True) @@ -100,7 +109,7 @@ class SecurityErrorTestCase(ExceptionTestCase): risky_info = uuid.uuid4().hex e = exception.Unauthorized(message=risky_info) self.assertValidJsonRendering(e) - self.assertIn(risky_info, str(e)) + self.assertIn(risky_info, unicode(e)) def test_forbidden_exposure(self): self.opt(debug=False) @@ -108,7 +117,7 @@ class SecurityErrorTestCase(ExceptionTestCase): risky_info = uuid.uuid4().hex e = exception.Forbidden(message=risky_info) self.assertValidJsonRendering(e) - self.assertNotIn(risky_info, str(e)) + self.assertNotIn(risky_info, unicode(e)) def test_forbidden_exposure_in_debug(self): self.opt(debug=True) @@ -116,7 +125,7 @@ class SecurityErrorTestCase(ExceptionTestCase): risky_info = uuid.uuid4().hex e = exception.Forbidden(message=risky_info) self.assertValidJsonRendering(e) - self.assertIn(risky_info, str(e)) + self.assertIn(risky_info, unicode(e)) def test_forbidden_action_exposure(self): self.opt(debug=False) @@ -125,12 +134,12 @@ class SecurityErrorTestCase(ExceptionTestCase): action = uuid.uuid4().hex e = exception.ForbiddenAction(message=risky_info, action=action) self.assertValidJsonRendering(e) - self.assertNotIn(risky_info, str(e)) - self.assertIn(action, str(e)) + self.assertNotIn(risky_info, unicode(e)) + self.assertIn(action, unicode(e)) e = exception.ForbiddenAction(action=risky_info) self.assertValidJsonRendering(e) - self.assertIn(risky_info, str(e)) + self.assertIn(risky_info, unicode(e)) def test_forbidden_action_exposure_in_debug(self): self.opt(debug=True) @@ -139,17 +148,16 @@ class SecurityErrorTestCase(ExceptionTestCase): e = exception.ForbiddenAction(message=risky_info) self.assertValidJsonRendering(e) - self.assertIn(risky_info, str(e)) + self.assertIn(risky_info, unicode(e)) e = exception.ForbiddenAction(action=risky_info) self.assertValidJsonRendering(e) - self.assertIn(risky_info, str(e)) + self.assertIn(risky_info, unicode(e)) - def test_unicode_message(self): - message = u'Comment \xe7a va' - e = exception.Error(message) - self.assertEqual(e.message, message) - try: - unicode(e) - except UnicodeEncodeError: - self.fail("unicode error message not supported") + def test_unicode_argument_message(self): + self.opt(debug=False) + + risky_info = u'\u7ee7\u7eed\u884c\u7f29\u8fdb\u6216' + e = exception.Forbidden(message=risky_info) + self.assertValidJsonRendering(e) + self.assertNotIn(risky_info, unicode(e)) diff --git a/tests/test_import_legacy.py b/tests/test_import_legacy.py index bafc076a..9e164099 100644 --- a/tests/test_import_legacy.py +++ b/tests/test_import_legacy.py @@ -25,7 +25,6 @@ from keystone import test from keystone.catalog.backends import templated as catalog_templated from keystone.common.sql import legacy -from keystone.common.sql import util as sql_util from keystone import config from keystone import identity from keystone.identity.backends import sql as identity_sql @@ -41,17 +40,17 @@ class ImportLegacy(test.TestCase): test.testsdir('test_overrides.conf'), test.testsdir('backend_sql.conf'), test.testsdir('backend_sql_disk.conf')]) - sql_util.setup_test_database() + test.setup_test_database() self.identity_man = identity.Manager() self.identity_api = identity_sql.Identity() def tearDown(self): - sql_util.teardown_test_database() + test.teardown_test_database() super(ImportLegacy, self).tearDown() def setup_old_database(self, sql_dump): sql_path = test.testsdir(sql_dump) - db_path = test.testsdir('%s.db' % sql_dump) + db_path = test.tmpdir('%s.db' % sql_dump) try: os.unlink(db_path) except OSError: @@ -73,7 +72,7 @@ class ImportLegacy(test.TestCase): self.assertEquals(user_ref['enabled'], True) # check password hashing - user_ref, tenant_ref, metadata_ref = self.identity_man.authenticate( + user_ref = self.identity_man.authenticate( user_id=admin_id, password='secrete') # check catalog @@ -90,7 +89,7 @@ class ImportLegacy(test.TestCase): self.assertEquals(user_ref['enabled'], True) # check password hashing - user_ref, tenant_ref, metadata_ref = self.identity_man.authenticate( + user_ref = self.identity_man.authenticate( user_id=admin_id, password='secrete') # check catalog @@ -107,7 +106,7 @@ class ImportLegacy(test.TestCase): self.assertEquals(user_ref['enabled'], True) # check password hashing - user_ref, tenant_ref, metadata_ref = self.identity_man.authenticate( + user_ref = self.identity_man.authenticate( user_id=admin_id, password='secrete') # check catalog diff --git a/tests/test_injection.py b/tests/test_injection.py index 4b6fc8ba..36cd0126 100644 --- a/tests/test_injection.py +++ b/tests/test_injection.py @@ -21,6 +21,10 @@ from keystone.common import dependency class TestDependencyInjection(unittest.TestCase): + def tearDown(self): + dependency.reset() + super(TestDependencyInjection, self).tearDown() + def test_dependency_injection(self): class Interface(object): def do_work(self): @@ -165,3 +169,43 @@ class TestDependencyInjection(unittest.TestCase): with self.assertRaises(dependency.UnresolvableDependencyException): Consumer() + dependency.resolve_future_dependencies() + + def test_circular_dependency(self): + p1_name = uuid.uuid4().hex + p2_name = uuid.uuid4().hex + + @dependency.provider(p1_name) + @dependency.requires(p2_name) + class P1(object): + pass + + @dependency.provider(p2_name) + @dependency.requires(p1_name) + class P2(object): + pass + + p1 = P1() + p2 = P2() + + dependency.resolve_future_dependencies() + + self.assertIs(getattr(p1, p2_name), p2) + self.assertIs(getattr(p2, p1_name), p1) + + def test_reset(self): + # Can reset the registry of providers. + + p_id = uuid.uuid4().hex + + @dependency.provider(p_id) + class P(object): + pass + + p_inst = P() + + self.assertIs(dependency.REGISTRY[p_id], p_inst) + + dependency.reset() + + self.assertFalse(dependency.REGISTRY) diff --git a/tests/test_keystoneclient.py b/tests/test_keystoneclient.py index b9828559..38062d4b 100644 --- a/tests/test_keystoneclient.py +++ b/tests/test_keystoneclient.py @@ -17,8 +17,6 @@ import uuid import webob -import nose.exc - from keystone import test from keystone import config @@ -37,23 +35,25 @@ class CompatTestCase(test.TestCase): def setUp(self): super(CompatTestCase, self).setUp() - revdir = test.checkout_vendor(*self.get_checkout()) - self.add_path(revdir) - self.clear_module('keystoneclient') + # The backends should be loaded and initialized before the servers are + # started because the servers use the backends. self.load_backends() self.load_fixtures(default_fixtures) + # TODO(termie): add an admin user to the fixtures and use that user + # override the fixtures, for now + self.metadata_foobar = self.identity_api.add_role_to_user_and_project( + self.user_foo['id'], + self.tenant_bar['id'], + self.role_admin['id']) + self.public_server = self.serveapp('keystone', name='main') self.admin_server = self.serveapp('keystone', name='admin') - # TODO(termie): is_admin is being deprecated once the policy stuff - # is all working - # TODO(termie): add an admin user to the fixtures and use that user - # override the fixtures, for now - self.metadata_foobar = self.identity_api.update_metadata( - self.user_foo['id'], self.tenant_bar['id'], - dict(roles=[self.role_admin['id']], is_admin='1')) + revdir = test.checkout_vendor(*self.get_checkout()) + self.add_path(revdir) + self.clear_module('keystoneclient') def tearDown(self): self.public_server.kill() @@ -537,7 +537,7 @@ class KeystoneClientTests(object): user=uuid.uuid4().hex) def test_user_update_tenant_404(self): - raise nose.exc.SkipTest('N/A') + self.skipTest('N/A') from keystoneclient import exceptions as client_exceptions client = self.get_client(admin=True) self.assertRaises(client_exceptions.NotFound, @@ -840,6 +840,28 @@ class KcMasterTestCase(CompatTestCase, KeystoneClientTests): def get_checkout(self): return KEYSTONECLIENT_REPO, 'master' + def test_ec2_auth(self): + client = self.get_client() + cred = client.ec2.create(user_id=self.user_foo['id'], + tenant_id=self.tenant_bar['id']) + + from keystoneclient.contrib.ec2 import utils as ec2_utils + signer = ec2_utils.Ec2Signer(cred.secret) + credentials = {'params': {'SignatureVersion': '2'}, + 'access': cred.access, + 'verb': 'GET', + 'host': 'localhost', + 'path': '/thisisgoingtowork'} + signature = signer.generate(credentials) + credentials['signature'] = signature + url = '%s/ec2tokens' % (client.auth_url) + (resp, token) = client.request(url=url, + method='POST', + body={'credentials': credentials}) + # make sure we have a v2 token + self.assertEqual(resp.status_code, 200) + self.assertIn('access', token) + def test_tenant_add_and_remove_user(self): client = self.get_client(admin=True) client.roles.add_user_role(tenant=self.tenant_bar['id'], @@ -1086,10 +1108,10 @@ class KcEssex3TestCase(CompatTestCase, KeystoneClientTests): self.assertTrue(len(roles) > 0) def test_role_list_404(self): - raise nose.exc.SkipTest('N/A') + self.skipTest('N/A') def test_authenticate_and_delete_token(self): - raise nose.exc.SkipTest('N/A') + self.skipTest('N/A') def test_user_create_update_delete(self): from keystoneclient import exceptions as client_exceptions @@ -1133,16 +1155,16 @@ class KcEssex3TestCase(CompatTestCase, KeystoneClientTests): user.id) def test_user_update_404(self): - raise nose.exc.SkipTest('N/A') + self.skipTest('N/A') def test_endpoint_create_404(self): - raise nose.exc.SkipTest('N/A') + self.skipTest('N/A') def test_endpoint_delete_404(self): - raise nose.exc.SkipTest('N/A') + self.skipTest('N/A') def test_policy_crud(self): - raise nose.exc.SkipTest('N/A due to lack of endpoint CRUD') + self.skipTest('N/A due to lack of endpoint CRUD') class Kc11TestCase(CompatTestCase, KeystoneClientTests): @@ -1150,4 +1172,4 @@ class Kc11TestCase(CompatTestCase, KeystoneClientTests): return KEYSTONECLIENT_REPO, '0.1.1' def test_policy_crud(self): - raise nose.exc.SkipTest('N/A') + self.skipTest('N/A') diff --git a/tests/test_keystoneclient_sql.py b/tests/test_keystoneclient_sql.py index 5706bef5..166d808c 100644 --- a/tests/test_keystoneclient_sql.py +++ b/tests/test_keystoneclient_sql.py @@ -16,8 +16,6 @@ import uuid -import nose.exc - from keystone import test from keystone.common import sql @@ -109,7 +107,7 @@ class KcMasterSqlTestCase(test_keystoneclient.KcMasterTestCase, sql.Base): # the client and essentially refers to a non-existent # policy manager in the v2 client. this test needs to be # moved to a test suite running against the v3 api - raise nose.exc.SkipTest('Written prior to v3 client; needs refactor') + self.skipTest('Written prior to v3 client; needs refactor') from keystoneclient import exceptions as client_exceptions client = self.get_client(admin=True) diff --git a/tests/test_middleware.py b/tests/test_middleware.py index 38ba09e9..9f9d3fd2 100644 --- a/tests/test_middleware.py +++ b/tests/test_middleware.py @@ -154,7 +154,7 @@ class XmlBodyMiddlewareTest(test.TestCase): self.assertTrue(jsonutils.loads(req.body)) def test_json_unnaffected(self): - """JSON-only requests should be unnaffected by the XML middleware.""" + """JSON-only requests should be unaffected by the XML middleware.""" content_type = 'application/json' body = '{"container": {"attribute": "value"}}' req = make_request(body=body, content_type=content_type, method='POST') diff --git a/tests/test_migrate_nova_auth.py b/tests/test_migrate_nova_auth.py deleted file mode 100644 index 3a122940..00000000 --- a/tests/test_migrate_nova_auth.py +++ /dev/null @@ -1,157 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack LLC -# -# 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 uuid - -from keystone import test - -from keystone.common.sql import nova -from keystone.common.sql import util as sql_util -from keystone import config -from keystone.contrib.ec2.backends import sql as ec2_sql -from keystone import identity - - -CONF = config.CONF -DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id - - -FIXTURE = { - 'users': [ - {'id': 'user1', 'name': 'uname1', 'password': 'acc1'}, - {'id': 'user4', 'name': 'uname4', 'password': 'acc1'}, - {'id': 'user2', 'name': 'uname2', 'password': 'acc2'}, - {'id': 'user3', 'name': 'uname3', 'password': 'acc3'}, - ], - 'roles': ['role1', 'role2', 'role3'], - 'role_user_tenant_list': [ - {'user_id': 'user1', 'role': 'role1', 'tenant_id': 'proj1'}, - {'user_id': 'user1', 'role': 'role2', 'tenant_id': 'proj1'}, - {'user_id': 'user4', 'role': 'role1', 'tenant_id': 'proj4'}, - {'user_id': 'user2', 'role': 'role1', 'tenant_id': 'proj1'}, - {'user_id': 'user2', 'role': 'role1', 'tenant_id': 'proj2'}, - {'user_id': 'user2', 'role': 'role2', 'tenant_id': 'proj2'}, - {'user_id': 'user3', 'role': 'role3', 'tenant_id': 'proj1'}, - ], - 'user_tenant_list': [ - {'tenant_id': 'proj1', 'user_id': 'user1'}, - {'tenant_id': 'proj4', 'user_id': 'user4'}, - {'tenant_id': 'proj1', 'user_id': 'user2'}, - {'tenant_id': 'proj2', 'user_id': 'user2'}, - {'tenant_id': 'proj1', 'user_id': 'user3'}, - ], - 'ec2_credentials': [ - {'access_key': 'acc1', 'secret_key': 'sec1', 'user_id': 'user1'}, - {'access_key': 'acc4', 'secret_key': 'sec4', 'user_id': 'user4'}, - {'access_key': 'acc2', 'secret_key': 'sec2', 'user_id': 'user2'}, - {'access_key': 'acc3', 'secret_key': 'sec3', 'user_id': 'user3'}, - ], - 'tenants': [ - {'description': 'desc1', 'id': 'proj1', 'name': 'pname1'}, - {'description': 'desc4', 'id': 'proj4', 'name': 'pname4'}, - {'description': 'desc2', 'id': 'proj2', 'name': 'pname2'}, - ], -} - - -class MigrateNovaAuth(test.TestCase): - def setUp(self): - super(MigrateNovaAuth, self).setUp() - self.config([test.etcdir('keystone.conf.sample'), - test.testsdir('test_overrides.conf'), - test.testsdir('backend_sql.conf'), - test.testsdir('backend_sql_disk.conf')]) - sql_util.setup_test_database() - self.identity_api = identity.Manager() - self.ec2_api = ec2_sql.Ec2() - - def tearDown(self): - sql_util.teardown_test_database() - super(MigrateNovaAuth, self).tearDown() - - def _create_role(self, role_name): - role_id = uuid.uuid4().hex - role_dict = {'id': role_id, 'name': role_name} - self.identity_api.create_role(role_id, role_dict) - - def test_import(self): - self._create_role('role1') - - nova.import_auth(FIXTURE) - - users = {} - for user in ['user1', 'user2', 'user3', 'user4']: - users[user] = self.identity_api.get_user_by_name( - user, DEFAULT_DOMAIN_ID) - - tenants = {} - for tenant in ['proj1', 'proj2', 'proj4']: - tenants[tenant] = self.identity_api.get_project_by_name( - tenant, DEFAULT_DOMAIN_ID) - - membership_map = { - 'user1': ['proj1'], - 'user2': ['proj1', 'proj2'], - 'user3': ['proj1'], - 'user4': ['proj4'], - } - - for (old_user, old_projects) in membership_map.iteritems(): - user = users[old_user] - membership = self.identity_api.get_projects_for_user(user['id']) - expected = [tenants[t]['id'] for t in old_projects] - self.assertEqual(set(expected), set(membership)) - for tenant_id in membership: - password = None - for _user in FIXTURE['users']: - if _user['id'] == old_user: - password = _user['password'] - self.identity_api.authenticate(user['id'], tenant_id, password) - - for ec2_cred in FIXTURE['ec2_credentials']: - user_id = users[ec2_cred['user_id']]['id'] - for tenant_id in self.identity_api.get_projects_for_user(user_id): - access = '%s:%s' % (tenant_id, ec2_cred['access_key']) - cred = self.ec2_api.get_credential(access) - actual = cred['secret'] - expected = ec2_cred['secret_key'] - self.assertEqual(expected, actual) - - roles = self.identity_api.list_roles() - role_names = set([role['name'] for role in roles]) - self.assertEqual(role_names, set(['role2', 'role1', 'role3', - CONF.member_role_name])) - - assignment_map = { - 'user1': {'proj1': ['role1', 'role2']}, - 'user2': {'proj1': ['role1'], 'proj2': ['role1', 'role2']}, - 'user3': {'proj1': ['role3']}, - 'user4': {'proj4': ['role1']}, - } - - for (old_user, old_project_map) in assignment_map.iteritems(): - tenant_names = ['proj1', 'proj2', 'proj4'] - for tenant_name in tenant_names: - user = users[old_user] - tenant = tenants[tenant_name] - roles = self.identity_api.get_roles_for_user_and_project( - user['id'], tenant['id']) - actual = [self.identity_api.get_role(role_id)['name'] - for role_id in roles] - if CONF.member_role_name in actual: - actual.remove(CONF.member_role_name) - expected = old_project_map.get(tenant_name, []) - self.assertEqual(set(actual), set(expected)) diff --git a/tests/test_no_admin_token_auth.py b/tests/test_no_admin_token_auth.py new file mode 100644 index 00000000..ffdaa7a8 --- /dev/null +++ b/tests/test_no_admin_token_auth.py @@ -0,0 +1,47 @@ + +import os +import webtest + +from keystone import test + + +def _generate_paste_config(): + # Generate a file, based on keystone-paste.ini, that doesn't include + # admin_token_auth in the pipeline + + with open(test.etcdir('keystone-paste.ini'), 'r') as f: + contents = f.read() + + new_contents = contents.replace(' admin_token_auth ', ' ') + + with open(test.tmpdir('no_admin_token_auth-paste.ini'), 'w') as f: + f.write(new_contents) + + +class TestNoAdminTokenAuth(test.TestCase): + def setUp(self): + super(TestNoAdminTokenAuth, self).setUp() + self.load_backends() + + _generate_paste_config() + + self.admin_app = webtest.TestApp( + self.loadapp(test.tmpdir('no_admin_token_auth'), name='admin'), + extra_environ=dict(REMOTE_ADDR='127.0.0.1')) + + def tearDown(self): + self.admin_app = None + os.remove(test.tmpdir('no_admin_token_auth-paste.ini')) + + def test_request_no_admin_token_auth(self): + # This test verifies that if the admin_token_auth middleware isn't + # in the paste pipeline that users can still make requests. + + # Note(blk-u): Picked /v2.0/tenants because it's an operation that + # requires is_admin in the context, any operation that requires + # is_admin would work for this test. + REQ_PATH = '/v2.0/tenants' + + # If the following does not raise, then the test is successful. + self.admin_app.get(REQ_PATH, headers={'X-Auth-Token': 'NotAdminToken'}, + status=401) diff --git a/tests/test_pki_token_provider.conf b/tests/test_pki_token_provider.conf new file mode 100644 index 00000000..255972c3 --- /dev/null +++ b/tests/test_pki_token_provider.conf @@ -0,0 +1,2 @@ +[token] +provider = keystone.token.providers.pki.Provider diff --git a/tests/test_sql_core.py b/tests/test_sql_core.py index d8f2a4f7..e60005f5 100644 --- a/tests/test_sql_core.py +++ b/tests/test_sql_core.py @@ -17,6 +17,130 @@ from keystone.common import sql from keystone import test +class CallbackMonitor: + def __init__(self, expect_called=True, raise_=False): + self.expect_called = expect_called + self.called = False + self._complete = False + self._raise = raise_ + + def call_this(self): + if self._complete: + return + + if not self.expect_called: + raise Exception("Did not expect callback.") + + if self.called: + raise Exception("Callback already called.") + + self.called = True + + if self._raise: + raise Exception("When called, raises.") + + def check(self): + if self.expect_called: + if not self.called: + raise Exception("Expected function to be called.") + self._complete = True + + +class TestGlobalEngine(test.TestCase): + + def tearDown(self): + sql.set_global_engine(None) + super(TestGlobalEngine, self).tearDown() + + def test_notify_on_set(self): + # If call sql.set_global_engine(), notify callbacks get called. + + cb_mon = CallbackMonitor() + + sql.register_global_engine_callback(cb_mon.call_this) + fake_engine = object() + sql.set_global_engine(fake_engine) + + cb_mon.check() + + def test_multi_notify(self): + # You can also set multiple notify callbacks and they each get called. + + cb_mon1 = CallbackMonitor() + cb_mon2 = CallbackMonitor() + + sql.register_global_engine_callback(cb_mon1.call_this) + sql.register_global_engine_callback(cb_mon2.call_this) + + fake_engine = object() + sql.set_global_engine(fake_engine) + + cb_mon1.check() + cb_mon2.check() + + def test_notify_once(self): + # After a callback is called, it's not called again if set global + # engine again. + + cb_mon = CallbackMonitor() + + sql.register_global_engine_callback(cb_mon.call_this) + fake_engine = object() + sql.set_global_engine(fake_engine) + + fake_engine = object() + # Note that cb_mon.call_this would raise if it's called again. + sql.set_global_engine(fake_engine) + + cb_mon.check() + + def test_set_same_engine(self): + # If you set the global engine to the same engine, callbacks don't get + # called. + + fake_engine = object() + + sql.set_global_engine(fake_engine) + + cb_mon = CallbackMonitor(expect_called=False) + sql.register_global_engine_callback(cb_mon.call_this) + + # Note that cb_mon.call_this would raise if it's called. + sql.set_global_engine(fake_engine) + + cb_mon.check() + + def test_notify_register_same(self): + # If you register the same callback twice, only gets called once. + cb_mon = CallbackMonitor() + + sql.register_global_engine_callback(cb_mon.call_this) + sql.register_global_engine_callback(cb_mon.call_this) + + fake_engine = object() + # Note that cb_mon.call_this would raise if it's called twice. + sql.set_global_engine(fake_engine) + + cb_mon.check() + + def test_callback_throws(self): + # If a callback function raises, + # a) the caller doesn't know about it, + # b) other callbacks are still called + + cb_mon1 = CallbackMonitor(raise_=True) + cb_mon2 = CallbackMonitor() + + sql.register_global_engine_callback(cb_mon1.call_this) + sql.register_global_engine_callback(cb_mon2.call_this) + + fake_engine = object() + sql.set_global_engine(fake_engine) + + cb_mon1.check() + cb_mon2.check() + + class TestBase(test.TestCase): def tearDown(self): @@ -38,3 +162,21 @@ class TestBase(test.TestCase): engine1 = base.get_engine() engine2 = base.get_engine(allow_global_engine=False) self.assertIsNot(engine1, engine2) + + def test_get_session(self): + # autocommit and expire_on_commit flags to get_session() are passed on + # to the session created. + + base = sql.Base() + session = base.get_session(autocommit=False, expire_on_commit=True) + + self.assertFalse(session.autocommit) + self.assertTrue(session.expire_on_commit) + + def test_get_session_invalidated(self): + # If clear the global engine, a new engine is used for get_session(). + base = sql.Base() + session1 = base.get_session() + sql.set_global_engine(None) + session2 = base.get_session() + self.assertIsNot(session1.bind, session2.bind) diff --git a/tests/test_sql_upgrade.py b/tests/test_sql_upgrade.py index ac4e5637..cf82b814 100644 --- a/tests/test_sql_upgrade.py +++ b/tests/test_sql_upgrade.py @@ -506,6 +506,10 @@ class SqlUpgradeTests(test.TestCase): def test_downgrade_to_0(self): self.upgrade(self.max_version) + + if self.engine.name == 'mysql': + self._mysql_check_all_tables_innodb() + self.downgrade(0) for table_name in ["user", "token", "role", "user_tenant_membership", "metadata"]: @@ -590,6 +594,22 @@ class SqlUpgradeTests(test.TestCase): 'data': json.dumps({"roles": [role2['id']]})} session.execute(metadata_table.insert().values(role_grant)) + # Create another user to test the case where member_role_id is already + # assigned. + user2 = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex, + 'domain_id': domain['id'], + 'password': uuid.uuid4().hex, + 'enabled': True, + 'extra': json.dumps({})} + session.execute(user_table.insert().values(user2)) + + # Grant CONF.member_role_id to User2 + role_grant = {'user_id': user2['id'], + 'tenant_id': project['id'], + 'data': json.dumps({"roles": [CONF.member_role_id]})} + session.execute(metadata_table.insert().values(role_grant)) + session.commit() self.upgrade(17) @@ -597,17 +617,19 @@ class SqlUpgradeTests(test.TestCase): user_project_metadata_table = sqlalchemy.Table( 'user_project_metadata', self.metadata, autoload=True) - r = session.execute('select data from metadata where ' - 'user_id=:user and tenant_id=:tenant', - {'user': user['id'], 'tenant': project['id']}) + s = sqlalchemy.select([metadata_table.c.data]).where( + (metadata_table.c.user_id == user['id']) & + (metadata_table.c.tenant_id == project['id'])) + r = session.execute(s) test_project1 = json.loads(r.fetchone()['data']) self.assertEqual(len(test_project1['roles']), 1) self.assertIn(role['id'], test_project1['roles']) # Test user in project2 has role2 - r = session.execute('select data from metadata where ' - 'user_id=:user and tenant_id=:tenant', - {'user': user['id'], 'tenant': project2['id']}) + s = sqlalchemy.select([metadata_table.c.data]).where( + (metadata_table.c.user_id == user['id']) & + (metadata_table.c.tenant_id == project2['id'])) + r = session.execute(s) test_project2 = json.loads(r.fetchone()['data']) self.assertEqual(len(test_project2['roles']), 1) self.assertIn(role2['id'], test_project2['roles']) @@ -615,9 +637,10 @@ class SqlUpgradeTests(test.TestCase): # Test for user in project has role in user_project_metadata # Migration 17 does not properly migrate this data, so this should # be None. - r = session.execute('select data from user_project_metadata where ' - 'user_id=:user and project_id=:project', - {'user': user['id'], 'project': project['id']}) + s = sqlalchemy.select([user_project_metadata_table.c.data]).where( + (user_project_metadata_table.c.user_id == user['id']) & + (user_project_metadata_table.c.project_id == project['id'])) + r = session.execute(s) self.assertIsNone(r.fetchone()) # Create a conflicting user-project in user_project_metadata with @@ -628,6 +651,14 @@ class SqlUpgradeTests(test.TestCase): 'data': data} cmd = user_project_metadata_table.insert().values(role_grant) self.engine.execute(cmd) + + # Create another conflicting user-project for User2 + data = json.dumps({"roles": [role2['id']]}) + role_grant = {'user_id': user2['id'], + 'project_id': project['id'], + 'data': data} + cmd = user_project_metadata_table.insert().values(role_grant) + self.engine.execute(cmd) # End Scaffolding session.commit() @@ -638,9 +669,10 @@ class SqlUpgradeTests(test.TestCase): # The user-project pairs should have all roles from the previous # metadata table in addition to any roles currently in # user_project_metadata - r = session.execute('select data from user_project_metadata where ' - 'user_id=:user and project_id=:project', - {'user': user['id'], 'project': project['id']}) + s = sqlalchemy.select([user_project_metadata_table.c.data]).where( + (user_project_metadata_table.c.user_id == user['id']) & + (user_project_metadata_table.c.project_id == project['id'])) + r = session.execute(s) role_ids = json.loads(r.fetchone()['data'])['roles'] self.assertEqual(len(role_ids), 3) self.assertIn(CONF.member_role_id, role_ids) @@ -649,9 +681,10 @@ class SqlUpgradeTests(test.TestCase): # pairs that only existed in old metadata table should be in # user_project_metadata - r = session.execute('select data from user_project_metadata where ' - 'user_id=:user and project_id=:project', - {'user': user['id'], 'project': project2['id']}) + s = sqlalchemy.select([user_project_metadata_table.c.data]).where( + (user_project_metadata_table.c.user_id == user['id']) & + (user_project_metadata_table.c.project_id == project2['id'])) + r = session.execute(s) role_ids = json.loads(r.fetchone()['data'])['roles'] self.assertEqual(len(role_ids), 2) self.assertIn(CONF.member_role_id, role_ids) @@ -815,6 +848,344 @@ class SqlUpgradeTests(test.TestCase): self.assertEqual(ref.legacy_endpoint_id, legacy_endpoint_id) self.assertEqual(ref.extra, '{}') + def test_group_project_FK_fixup(self): + # To create test data we must start before we broke in the + # group_project_metadata table in 015. + self.upgrade(14) + session = self.Session() + + domain_table = sqlalchemy.Table('domain', self.metadata, autoload=True) + group_table = sqlalchemy.Table('group', self.metadata, autoload=True) + tenant_table = sqlalchemy.Table('tenant', self.metadata, autoload=True) + role_table = sqlalchemy.Table('role', self.metadata, autoload=True) + group_project_metadata_table = sqlalchemy.Table( + 'group_project_metadata', self.metadata, autoload=True) + + # Create a Domain + domain = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex, + 'enabled': True} + session.execute(domain_table.insert().values(domain)) + + # Create two Tenants + tenant = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex, + 'extra': "{}"} + session.execute(tenant_table.insert().values(tenant)) + + tenant1 = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex, + 'extra': "{}"} + session.execute(tenant_table.insert().values(tenant1)) + + # Create a Group + group = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex, + 'domain_id': domain['id'], + 'extra': json.dumps({})} + session.execute(group_table.insert().values(group)) + + # Create roles + role_list = [] + for _ in range(2): + role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + session.execute(role_table.insert().values(role)) + role_list.append(role) + + # Grant Role to User on Project + role_grant = {'group_id': group['id'], + 'project_id': tenant['id'], + 'data': json.dumps({'roles': [role_list[0]['id']]})} + session.execute( + group_project_metadata_table.insert().values(role_grant)) + + role_grant = {'group_id': group['id'], + 'project_id': tenant1['id'], + 'data': json.dumps({'roles': [role_list[1]['id']]})} + session.execute( + group_project_metadata_table.insert().values(role_grant)) + + session.commit() + + # Now upgrade and fix up the FKs + self.upgrade(28) + self.assertTableExists('group_project_metadata') + self.assertTableExists('project') + self.assertTableDoesNotExist('tenant') + + s = sqlalchemy.select([group_project_metadata_table.c.data]).where( + (group_project_metadata_table.c.group_id == group['id']) & + (group_project_metadata_table.c.project_id == tenant['id'])) + r = session.execute(s) + data = json.loads(r.fetchone()['data']) + self.assertEqual(len(data['roles']), 1) + self.assertIn(role_list[0]['id'], data['roles']) + + s = sqlalchemy.select([group_project_metadata_table.c.data]).where( + (group_project_metadata_table.c.group_id == group['id']) & + (group_project_metadata_table.c.project_id == tenant1['id'])) + r = session.execute(s) + data = json.loads(r.fetchone()['data']) + self.assertEqual(len(data['roles']), 1) + self.assertIn(role_list[1]['id'], data['roles']) + + self.downgrade(27) + self.assertTableExists('group_project_metadata') + self.assertTableExists('project') + self.assertTableDoesNotExist('tenant') + + def test_assignment_metadata_migration(self): + self.upgrade(28) + # Scaffolding + session = self.Session() + + domain_table = sqlalchemy.Table('domain', self.metadata, autoload=True) + user_table = sqlalchemy.Table('user', self.metadata, autoload=True) + group_table = sqlalchemy.Table('group', self.metadata, autoload=True) + role_table = sqlalchemy.Table('role', self.metadata, autoload=True) + project_table = sqlalchemy.Table( + 'project', self.metadata, autoload=True) + user_project_metadata_table = sqlalchemy.Table( + 'user_project_metadata', self.metadata, autoload=True) + user_domain_metadata_table = sqlalchemy.Table( + 'user_domain_metadata', self.metadata, autoload=True) + group_project_metadata_table = sqlalchemy.Table( + 'group_project_metadata', self.metadata, autoload=True) + group_domain_metadata_table = sqlalchemy.Table( + 'group_domain_metadata', self.metadata, autoload=True) + + # Create a Domain + domain = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex, + 'enabled': True} + session.execute(domain_table.insert().values(domain)) + + # Create anther Domain + domain2 = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex, + 'enabled': True} + session.execute(domain_table.insert().values(domain2)) + + # Create a Project + project = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex, + 'domain_id': domain['id'], + 'extra': "{}"} + session.execute(project_table.insert().values(project)) + + # Create another Project + project2 = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex, + 'domain_id': domain['id'], + 'extra': "{}"} + session.execute(project_table.insert().values(project2)) + + # Create a User + user = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex, + 'domain_id': domain['id'], + 'password': uuid.uuid4().hex, + 'enabled': True, + 'extra': json.dumps({})} + session.execute(user_table.insert().values(user)) + + # Create a Group + group = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex, + 'domain_id': domain['id'], + 'extra': json.dumps({})} + session.execute(group_table.insert().values(group)) + + # Create roles + role_list = [] + for _ in range(7): + role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + session.execute(role_table.insert().values(role)) + role_list.append(role) + + # Grant Role to User on Project + role_grant = {'user_id': user['id'], + 'project_id': project['id'], + 'data': json.dumps({'roles': [role_list[0]['id']]})} + session.execute( + user_project_metadata_table.insert().values(role_grant)) + + role_grant = {'user_id': user['id'], + 'project_id': project2['id'], + 'data': json.dumps({'roles': [role_list[1]['id']]})} + session.execute( + user_project_metadata_table.insert().values(role_grant)) + + # Grant Role to Group on different Project + role_grant = {'group_id': group['id'], + 'project_id': project2['id'], + 'data': json.dumps({'roles': [role_list[2]['id']]})} + session.execute( + group_project_metadata_table.insert().values(role_grant)) + + # Grant Role to User on Domain + role_grant = {'user_id': user['id'], + 'domain_id': domain['id'], + 'data': json.dumps({'roles': [role_list[3]['id']]})} + session.execute(user_domain_metadata_table.insert().values(role_grant)) + + # Grant Role to Group on Domain + role_grant = {'group_id': group['id'], + 'domain_id': domain['id'], + 'data': json.dumps( + {'roles': [role_list[4]['id']], + 'other': 'somedata'})} + session.execute( + group_domain_metadata_table.insert().values(role_grant)) + + session.commit() + + self.upgrade(29) + s = sqlalchemy.select([user_project_metadata_table.c.data]).where( + (user_project_metadata_table.c.user_id == user['id']) & + (user_project_metadata_table.c.project_id == project['id'])) + r = session.execute(s) + data = json.loads(r.fetchone()['data']) + self.assertEqual(len(data['roles']), 1) + self.assertIn({'id': role_list[0]['id']}, data['roles']) + + s = sqlalchemy.select([user_project_metadata_table.c.data]).where( + (user_project_metadata_table.c.user_id == user['id']) & + (user_project_metadata_table.c.project_id == project2['id'])) + r = session.execute(s) + data = json.loads(r.fetchone()['data']) + self.assertEqual(len(data['roles']), 1) + self.assertIn({'id': role_list[1]['id']}, data['roles']) + + s = sqlalchemy.select([group_project_metadata_table.c.data]).where( + (group_project_metadata_table.c.group_id == group['id']) & + (group_project_metadata_table.c.project_id == project2['id'])) + r = session.execute(s) + data = json.loads(r.fetchone()['data']) + self.assertEqual(len(data['roles']), 1) + self.assertIn({'id': role_list[2]['id']}, data['roles']) + + s = sqlalchemy.select([user_domain_metadata_table.c.data]).where( + (user_domain_metadata_table.c.user_id == user['id']) & + (user_domain_metadata_table.c.domain_id == domain['id'])) + r = session.execute(s) + data = json.loads(r.fetchone()['data']) + self.assertEqual(len(data['roles']), 1) + self.assertIn({'id': role_list[3]['id']}, data['roles']) + + s = sqlalchemy.select([group_domain_metadata_table.c.data]).where( + (group_domain_metadata_table.c.group_id == group['id']) & + (group_domain_metadata_table.c.domain_id == domain['id'])) + r = session.execute(s) + data = json.loads(r.fetchone()['data']) + self.assertEqual(len(data['roles']), 1) + self.assertIn({'id': role_list[4]['id']}, data['roles']) + self.assertIn('other', data) + + # Now add an entry that has one regular and one inherited role + role_grant = {'user_id': user['id'], + 'domain_id': domain2['id'], + 'data': json.dumps( + {'roles': [{'id': role_list[5]['id']}, + {'id': role_list[6]['id'], + 'inherited_to': 'projects'}]})} + session.execute(user_domain_metadata_table.insert().values(role_grant)) + + session.commit() + self.downgrade(28) + + s = sqlalchemy.select([user_project_metadata_table.c.data]).where( + (user_project_metadata_table.c.user_id == user['id']) & + (user_project_metadata_table.c.project_id == project['id'])) + r = session.execute(s) + data = json.loads(r.fetchone()['data']) + self.assertEqual(len(data['roles']), 1) + self.assertIn(role_list[0]['id'], data['roles']) + + s = sqlalchemy.select([user_project_metadata_table.c.data]).where( + (user_project_metadata_table.c.user_id == user['id']) & + (user_project_metadata_table.c.project_id == project2['id'])) + r = session.execute(s) + data = json.loads(r.fetchone()['data']) + self.assertEqual(len(data['roles']), 1) + self.assertIn(role_list[1]['id'], data['roles']) + + s = sqlalchemy.select([group_project_metadata_table.c.data]).where( + (group_project_metadata_table.c.group_id == group['id']) & + (group_project_metadata_table.c.project_id == project2['id'])) + r = session.execute(s) + data = json.loads(r.fetchone()['data']) + self.assertEqual(len(data['roles']), 1) + self.assertIn(role_list[2]['id'], data['roles']) + + s = sqlalchemy.select([user_domain_metadata_table.c.data]).where( + (user_domain_metadata_table.c.user_id == user['id']) & + (user_domain_metadata_table.c.domain_id == domain['id'])) + r = session.execute(s) + data = json.loads(r.fetchone()['data']) + self.assertEqual(len(data['roles']), 1) + self.assertIn(role_list[3]['id'], data['roles']) + + s = sqlalchemy.select([group_domain_metadata_table.c.data]).where( + (group_domain_metadata_table.c.group_id == group['id']) & + (group_domain_metadata_table.c.domain_id == domain['id'])) + r = session.execute(s) + data = json.loads(r.fetchone()['data']) + self.assertEqual(len(data['roles']), 1) + self.assertIn(role_list[4]['id'], data['roles']) + self.assertIn('other', data) + + # For user-domain2, where we had one regular and one inherited role, + # only the direct role should remain, the inherited role should + # have been deleted during the downgrade + s = sqlalchemy.select([user_domain_metadata_table.c.data]).where( + (user_domain_metadata_table.c.user_id == user['id']) & + (user_domain_metadata_table.c.domain_id == domain2['id'])) + r = session.execute(s) + data = json.loads(r.fetchone()['data']) + self.assertEqual(len(data['roles']), 1) + self.assertIn(role_list[5]['id'], data['roles']) + + def test_drop_credential_constraint(self): + ec2_credential = { + 'id': '100', + 'user_id': 'foo', + 'project_id': 'bar', + 'type': 'ec2', + 'blob': json.dumps({ + "access": "12345", + "secret": "12345" + }) + } + user = { + 'id': 'foo', + 'name': 'FOO', + 'password': 'foo2', + 'enabled': True, + 'email': 'foo@bar.com', + 'extra': json.dumps({'enabled': True}) + } + tenant = { + 'id': 'bar', + 'name': 'BAR', + 'description': 'description', + 'enabled': True, + 'extra': json.dumps({'enabled': True}) + } + session = self.Session() + self.upgrade(7) + self.insert_dict(session, 'user', user) + self.insert_dict(session, 'tenant', tenant) + self.insert_dict(session, 'credential', ec2_credential) + session.commit() + self.upgrade(30) + cred_table = sqlalchemy.Table('credential', + self.metadata, + autoload=True) + cred = session.query(cred_table).filter("id='100'").one() + self.assertEqual(cred.user_id, + ec2_credential['user_id']) + def populate_user_table(self, with_pass_enab=False, with_pass_enab_domain=False): # Populate the appropriate fields in the user @@ -956,3 +1327,26 @@ class SqlUpgradeTests(test.TestCase): for ver, change in changeset: self.schema.runchange(ver, change, changeset.step) self.assertEqual(self.schema.version, version) + + def _mysql_check_all_tables_innodb(self): + database = self.engine.url.database + + connection = self.engine.connect() + # sanity check + total = connection.execute("SELECT count(*) " + "from information_schema.TABLES " + "where TABLE_SCHEMA='%(database)s'" % + locals()) + self.assertTrue(total.scalar() > 0, "No tables found. Wrong schema?") + + noninnodb = connection.execute("SELECT table_name " + "from information_schema.TABLES " + "where TABLE_SCHEMA='%(database)s' " + "and ENGINE!='InnoDB' " + "and TABLE_NAME!='migrate_version'" % + locals()) + names = [x[0] for x in noninnodb] + self.assertEqual(names, [], + "Non-InnoDB tables exist") + + connection.close() diff --git a/tests/test_token_bind.py b/tests/test_token_bind.py new file mode 100644 index 00000000..20488a91 --- /dev/null +++ b/tests/test_token_bind.py @@ -0,0 +1,182 @@ +# Copyright 2013 OpenStack LLC +# +# 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. + +from keystone.common import wsgi +from keystone import config +from keystone import exception +from keystone import test + +CONF = config.CONF + +KERBEROS_BIND = 'USER@REALM' + +# the only thing the function checks for is the presence of bind +TOKEN_BIND_KERB = {'bind': {'kerberos': KERBEROS_BIND}} +TOKEN_BIND_UNKNOWN = {'bind': {'FOO': 'BAR'}} +TOKEN_BIND_NONE = {} + +ANY = 'any' +ALL_TOKENS = [TOKEN_BIND_KERB, TOKEN_BIND_UNKNOWN, TOKEN_BIND_NONE] + + +class BindTest(test.TestCase): + """Test binding tokens to a Principal. + + Even though everything in this file references kerberos the same concepts + will apply to all future binding mechanisms. + """ + + def assert_kerberos_bind(self, tokens, bind_level, + use_kerberos=True, success=True): + if not isinstance(tokens, dict): + for token in tokens: + self.assert_kerberos_bind(token, bind_level, + use_kerberos=use_kerberos, + success=success) + elif use_kerberos == ANY: + for val in (True, False): + self.assert_kerberos_bind(tokens, bind_level, + use_kerberos=val, success=success) + else: + context = {} + CONF.token.enforce_token_bind = bind_level + + if use_kerberos: + context['REMOTE_USER'] = KERBEROS_BIND + context['AUTH_TYPE'] = 'Negotiate' + + if not success: + self.assertRaises(exception.Unauthorized, + wsgi.validate_token_bind, + context, tokens) + else: + wsgi.validate_token_bind(context, tokens) + + # DISABLED + + def test_bind_disabled_with_kerb_user(self): + self.assert_kerberos_bind(ALL_TOKENS, + bind_level='disabled', + use_kerberos=ANY, + success=True) + + # PERMISSIVE + + def test_bind_permissive_with_kerb_user(self): + self.assert_kerberos_bind(TOKEN_BIND_KERB, + bind_level='permissive', + use_kerberos=True, + success=True) + + def test_bind_permissive_with_regular_token(self): + self.assert_kerberos_bind(TOKEN_BIND_NONE, + bind_level='permissive', + use_kerberos=ANY, + success=True) + + def test_bind_permissive_without_kerb_user(self): + self.assert_kerberos_bind(TOKEN_BIND_KERB, + bind_level='permissive', + use_kerberos=False, + success=False) + + def test_bind_permissive_with_unknown_bind(self): + self.assert_kerberos_bind(TOKEN_BIND_UNKNOWN, + bind_level='permissive', + use_kerberos=ANY, + success=True) + + # STRICT + + def test_bind_strict_with_regular_token(self): + self.assert_kerberos_bind(TOKEN_BIND_NONE, + bind_level='strict', + use_kerberos=ANY, + success=True) + + def test_bind_strict_with_kerb_user(self): + self.assert_kerberos_bind(TOKEN_BIND_KERB, + bind_level='strict', + use_kerberos=True, + success=True) + + def test_bind_strict_without_kerb_user(self): + self.assert_kerberos_bind(TOKEN_BIND_KERB, + bind_level='strict', + use_kerberos=False, + success=False) + + def test_bind_strict_with_unknown_bind(self): + self.assert_kerberos_bind(TOKEN_BIND_UNKNOWN, + bind_level='strict', + use_kerberos=ANY, + success=False) + + # REQUIRED + + def test_bind_required_with_regular_token(self): + self.assert_kerberos_bind(TOKEN_BIND_NONE, + bind_level='required', + use_kerberos=ANY, + success=False) + + def test_bind_required_with_kerb_user(self): + self.assert_kerberos_bind(TOKEN_BIND_KERB, + bind_level='required', + use_kerberos=True, + success=True) + + def test_bind_required_without_kerb_user(self): + self.assert_kerberos_bind(TOKEN_BIND_KERB, + bind_level='required', + use_kerberos=False, + success=False) + + def test_bind_required_with_unknown_bind(self): + self.assert_kerberos_bind(TOKEN_BIND_UNKNOWN, + bind_level='required', + use_kerberos=ANY, + success=False) + + # NAMED + + def test_bind_named_with_regular_token(self): + self.assert_kerberos_bind(TOKEN_BIND_NONE, + bind_level='kerberos', + use_kerberos=ANY, + success=False) + + def test_bind_named_with_kerb_user(self): + self.assert_kerberos_bind(TOKEN_BIND_KERB, + bind_level='kerberos', + use_kerberos=True, + success=True) + + def test_bind_named_without_kerb_user(self): + self.assert_kerberos_bind(TOKEN_BIND_KERB, + bind_level='kerberos', + use_kerberos=False, + success=False) + + def test_bind_named_with_unknown_bind(self): + self.assert_kerberos_bind(TOKEN_BIND_UNKNOWN, + bind_level='kerberos', + use_kerberos=ANY, + success=False) + + def test_bind_named_with_unknown_scheme(self): + self.assert_kerberos_bind(ALL_TOKENS, + bind_level='unknown', + use_kerberos=ANY, + success=False) diff --git a/tests/test_token_provider.py b/tests/test_token_provider.py new file mode 100644 index 00000000..a7e92717 --- /dev/null +++ b/tests/test_token_provider.py @@ -0,0 +1,439 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 OpenStack LLC +# +# 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 uuid + +from keystone import exception +from keystone import test +from keystone import token + + +SAMPLE_V2_TOKEN = { + "access": { + "trust": { + "id": "abc123", + "trustee_user_id": "123456" + }, + "serviceCatalog": [ + { + "endpoints": [ + { + "adminURL": "http://localhost:8774/v1.1/01257", + "id": "51934fe63a5b4ac0a32664f64eb462c3", + "internalURL": "http://localhost:8774/v1.1/01257", + "publicURL": "http://localhost:8774/v1.1/01257", + "region": "RegionOne" + } + ], + "endpoints_links": [], + "name": "nova", + "type": "compute" + }, + { + "endpoints": [ + { + "adminURL": "http://localhost:9292", + "id": "aaa17a539e364297a7845d67c7c7cc4b", + "internalURL": "http://localhost:9292", + "publicURL": "http://localhost:9292", + "region": "RegionOne" + } + ], + "endpoints_links": [], + "name": "glance", + "type": "image" + }, + { + "endpoints": [ + { + "adminURL": "http://localhost:8776/v1/01257", + "id": "077d82df25304abeac2294004441db5a", + "internalURL": "http://localhost:8776/v1/01257", + "publicURL": "http://localhost:8776/v1/01257", + "region": "RegionOne" + } + ], + "endpoints_links": [], + "name": "volume", + "type": "volume" + }, + { + "endpoints": [ + { + "adminURL": "http://localhost:8773/services/Admin", + "id": "b06997fd08414903ad458836efaa9067", + "internalURL": "http://localhost:8773/services/Cloud", + "publicURL": "http://localhost:8773/services/Cloud", + "region": "RegionOne" + } + ], + "endpoints_links": [], + "name": "ec2", + "type": "ec2" + }, + { + "endpoints": [ + { + "adminURL": "http://localhost:8888/v1", + "id": "7bd0c643e05a4a2ab40902b2fa0dd4e6", + "internalURL": "http://localhost:8888/v1/AUTH_01257", + "publicURL": "http://localhost:8888/v1/AUTH_01257", + "region": "RegionOne" + } + ], + "endpoints_links": [], + "name": "swift", + "type": "object-store" + }, + { + "endpoints": [ + { + "adminURL": "http://localhost:35357/v2.0", + "id": "02850c5d1d094887bdc46e81e1e15dc7", + "internalURL": "http://localhost:5000/v2.0", + "publicURL": "http://localhost:5000/v2.0", + "region": "RegionOne" + } + ], + "endpoints_links": [], + "name": "keystone", + "type": "identity" + } + ], + "token": { + "expires": "2013-05-22T00:02:43.941430Z", + "id": "ce4fc2d36eea4cc9a36e666ac2f1029a", + "issued_at": "2013-05-21T00:02:43.941473Z", + "tenant": { + "enabled": True, + "id": "01257", + "name": "service" + } + }, + "user": { + "id": "f19ddbe2c53c46f189fe66d0a7a9c9ce", + "name": "nova", + "roles": [ + { + "name": "_member_" + }, + { + "name": "admin" + } + ], + "roles_links": [], + "username": "nova" + } + } +} + +SAMPLE_V3_TOKEN = { + "token": { + "catalog": [ + { + "endpoints": [ + { + "id": "02850c5d1d094887bdc46e81e1e15dc7", + "interface": "admin", + "region": "RegionOne", + "url": "http://localhost:35357/v2.0" + }, + { + "id": "446e244b75034a9ab4b0811e82d0b7c8", + "interface": "internal", + "region": "RegionOne", + "url": "http://localhost:5000/v2.0" + }, + { + "id": "47fa3d9f499240abb5dfcf2668f168cd", + "interface": "public", + "region": "RegionOne", + "url": "http://localhost:5000/v2.0" + } + ], + "id": "26d7541715a44a4d9adad96f9872b633", + "type": "identity", + }, + { + "endpoints": [ + { + "id": "aaa17a539e364297a7845d67c7c7cc4b", + "interface": "admin", + "region": "RegionOne", + "url": "http://localhost:9292" + }, + { + "id": "4fa9620e42394cb1974736dce0856c71", + "interface": "internal", + "region": "RegionOne", + "url": "http://localhost:9292" + }, + { + "id": "9673687f9bc441d88dec37942bfd603b", + "interface": "public", + "region": "RegionOne", + "url": "http://localhost:9292" + } + ], + "id": "d27a41843f4e4b0e8cf6dac4082deb0d", + "type": "image", + }, + { + "endpoints": [ + { + "id": "7bd0c643e05a4a2ab40902b2fa0dd4e6", + "interface": "admin", + "region": "RegionOne", + "url": "http://localhost:8888/v1" + }, + { + "id": "43bef154594d4ccb8e49014d20624e1d", + "interface": "internal", + "region": "RegionOne", + "url": "http://localhost:8888/v1/AUTH_01257" + }, + { + "id": "e63b5f5d7aa3493690189d0ff843b9b3", + "interface": "public", + "region": "RegionOne", + "url": "http://localhost:8888/v1/AUTH_01257" + } + ], + "id": "a669e152f1104810a4b6701aade721bb", + "type": "object-store", + }, + { + "endpoints": [ + { + "id": "51934fe63a5b4ac0a32664f64eb462c3", + "interface": "admin", + "region": "RegionOne", + "url": "http://localhost:8774/v1.1/01257" + }, + { + "id": "869b535eea0d42e483ae9da0d868ebad", + "interface": "internal", + "region": "RegionOne", + "url": "http://localhost:8774/v1.1/01257" + }, + { + "id": "93583824c18f4263a2245ca432b132a6", + "interface": "public", + "region": "RegionOne", + "url": "http://localhost:8774/v1.1/01257" + } + ], + "id": "7f32cc2af6c9476e82d75f80e8b3bbb8", + "type": "compute", + }, + { + "endpoints": [ + { + "id": "b06997fd08414903ad458836efaa9067", + "interface": "admin", + "region": "RegionOne", + "url": "http://localhost:8773/services/Admin" + }, + { + "id": "411f7de7c9a8484c9b46c254fb2676e2", + "interface": "internal", + "region": "RegionOne", + "url": "http://localhost:8773/services/Cloud" + }, + { + "id": "f21c93f3da014785854b4126d0109c49", + "interface": "public", + "region": "RegionOne", + "url": "http://localhost:8773/services/Cloud" + } + ], + "id": "b08c9c7d4ef543eba5eeb766f72e5aa1", + "type": "ec2", + }, + { + "endpoints": [ + { + "id": "077d82df25304abeac2294004441db5a", + "interface": "admin", + "region": "RegionOne", + "url": "http://localhost:8776/v1/01257" + }, + { + "id": "875bf282362c40219665278b4fd11467", + "interface": "internal", + "region": "RegionOne", + "url": "http://localhost:8776/v1/01257" + }, + { + "id": "cd229aa6df0640dc858a8026eb7e640c", + "interface": "public", + "region": "RegionOne", + "url": "http://localhost:8776/v1/01257" + } + ], + "id": "5db21b82617f4a95816064736a7bec22", + "type": "volume", + } + ], + "expires_at": "2013-05-22T00:02:43.941430Z", + "issued_at": "2013-05-21T00:02:43.941473Z", + "methods": [ + "password" + ], + "project": { + "domain": { + "id": "default", + "name": "Default" + }, + "id": "01257", + "name": "service" + }, + "roles": [ + { + "id": "9fe2ff9ee4384b1894a90878d3e92bab", + "name": "_member_" + }, + { + "id": "53bff13443bd4450b97f978881d47b18", + "name": "admin" + } + ], + "user": { + "domain": { + "id": "default", + "name": "Default" + }, + "id": "f19ddbe2c53c46f189fe66d0a7a9c9ce", + "name": "nova" + }, + "OS-TRUST:trust": { + "id": "abc123", + "trustee_user_id": "123456", + "trustor_user_id": "333333", + "impersonation": False + } + } +} + + +class TestTokenProvider(test.TestCase): + def setUp(self): + super(TestTokenProvider, self).setUp() + self.load_backends() + + def test_get_token_version(self): + self.assertEqual( + token.provider.V2, + self.token_provider_api.get_token_version(SAMPLE_V2_TOKEN)) + self.assertEqual( + token.provider.V3, + self.token_provider_api.get_token_version(SAMPLE_V3_TOKEN)) + self.assertRaises(token.provider.UnsupportedTokenVersionException, + self.token_provider_api.get_token_version, + 'bogus') + + def test_issue_token(self): + self.assertRaises(token.provider.UnsupportedTokenVersionException, + self.token_provider_api.issue_token, + 'bogus_version') + + def test_validate_token(self): + self.assertRaises(token.provider.UnsupportedTokenVersionException, + self.token_provider_api.validate_token, + uuid.uuid4().hex, + None, + 'bogus_version') + + def test_token_format_provider_mismatch(self): + self.opt_in_group('signing', token_format='UUID') + self.opt_in_group('token', + provider=token.provider.PKI_PROVIDER) + try: + token.provider.Manager() + raise Exception( + 'expecting ValueError on token provider misconfiguration') + except exception.UnexpectedError: + pass + + self.opt_in_group('signing', token_format='PKI') + self.opt_in_group('token', + provider=token.provider.UUID_PROVIDER) + try: + token.provider.Manager() + raise Exception( + 'expecting ValueError on token provider misconfiguration') + except exception.UnexpectedError: + pass + + # should be OK as token_format and provider aligns + self.opt_in_group('signing', token_format='PKI') + self.opt_in_group('token', + provider=token.provider.PKI_PROVIDER) + token.provider.Manager() + + self.opt_in_group('signing', token_format='UUID') + self.opt_in_group('token', + provider=token.provider.UUID_PROVIDER) + token.provider.Manager() + + # custom provider should be OK too + self.opt_in_group('signing', token_format='CUSTOM') + self.opt_in_group('token', + provider=token.provider.PKI_PROVIDER) + token.provider.Manager() + + def test_default_token_format(self): + self.assertEqual(token.provider.Manager.get_token_provider(), + token.provider.PKI_PROVIDER) + + def test_uuid_token_format_and_no_provider(self): + self.opt_in_group('signing', token_format='UUID') + self.assertEqual(token.provider.Manager.get_token_provider(), + token.provider.UUID_PROVIDER) + + def test_unsupported_token_format(self): + self.opt_in_group('signing', token_format='CUSTOM') + self.assertRaises(exception.UnexpectedError, + token.provider.Manager.get_token_provider) + + def test_uuid_provider(self): + self.opt_in_group('token', provider=token.provider.UUID_PROVIDER) + self.assertEqual(token.provider.Manager.get_token_provider(), + token.provider.UUID_PROVIDER) + + def test_provider_override_token_format(self): + self.opt_in_group('token', + provider='keystone.token.providers.pki.Test') + self.assertEqual(token.provider.Manager.get_token_provider(), + 'keystone.token.providers.pki.Test') + + self.opt_in_group('signing', token_format='UUID') + self.opt_in_group('token', + provider=token.provider.UUID_PROVIDER) + self.assertEqual(token.provider.Manager.get_token_provider(), + token.provider.UUID_PROVIDER) + + self.opt_in_group('signing', token_format='PKI') + self.opt_in_group('token', + provider=token.provider.PKI_PROVIDER) + self.assertEqual(token.provider.Manager.get_token_provider(), + token.provider.PKI_PROVIDER) + + self.opt_in_group('signing', token_format='CUSTOM') + self.opt_in_group('token', + provider='my.package.MyProvider') + self.assertEqual(token.provider.Manager.get_token_provider(), + 'my.package.MyProvider') diff --git a/tests/test_uuid_token_provider.conf b/tests/test_uuid_token_provider.conf new file mode 100644 index 00000000..d127ea3b --- /dev/null +++ b/tests/test_uuid_token_provider.conf @@ -0,0 +1,2 @@ +[token] +provider = keystone.token.providers.uuid.Provider diff --git a/tests/test_v3.py b/tests/test_v3.py index 93293b6c..4f00de7d 100644 --- a/tests/test_v3.py +++ b/tests/test_v3.py @@ -8,7 +8,6 @@ from keystone import test from keystone import auth from keystone.common import serializer -from keystone.common.sql import util as sql_util from keystone import config from keystone.openstack.common import timeutils from keystone.policy.backends import rules @@ -23,6 +22,15 @@ TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ' class RestfulTestCase(test_content_types.RestfulTestCase): + _config_file_list = [test.etcdir('keystone.conf.sample'), + test.testsdir('test_overrides.conf'), + test.testsdir('backend_sql.conf'), + test.testsdir('backend_sql_disk.conf')] + + #override this to sepcify the complete list of configuration files + def config_files(self): + return self._config_file_list + def setUp(self, load_sample_data=True): """Setup for v3 Restful Test Cases. @@ -31,13 +39,9 @@ class RestfulTestCase(test_content_types.RestfulTestCase): load_sample_data should be set to false. """ - self.config([ - test.etcdir('keystone.conf.sample'), - test.testsdir('test_overrides.conf'), - test.testsdir('backend_sql.conf'), - test.testsdir('backend_sql_disk.conf')]) + self.config(self.config_files()) - sql_util.setup_test_database() + test.setup_test_database() self.load_backends() self.public_app = webtest.TestApp( @@ -102,7 +106,7 @@ class RestfulTestCase(test_content_types.RestfulTestCase): self.admin_server.kill() self.public_server = None self.admin_server = None - sql_util.teardown_test_database() + test.teardown_test_database() # need to reset the plug-ins auth.controllers.AUTH_METHODS = {} #drop the policy rules @@ -331,7 +335,7 @@ class RestfulTestCase(test_content_types.RestfulTestCase): links['previous']) def assertValidListResponse(self, resp, key, entity_validator, ref=None, - expected_length=None): + expected_length=None, keys_to_check=None): """Make assertions common to all API list responses. If a reference is provided, it's ID will be searched for in the @@ -352,11 +356,12 @@ class RestfulTestCase(test_content_types.RestfulTestCase): for entity in entities: self.assertIsNotNone(entity) - self.assertValidEntity(entity) + self.assertValidEntity(entity, keys_to_check=keys_to_check) entity_validator(entity) if ref: entity = [x for x in entities if x['id'] == ref['id']][0] - self.assertValidEntity(entity, ref) + self.assertValidEntity(entity, ref=ref, + keys_to_check=keys_to_check) entity_validator(entity, ref) return entities @@ -365,17 +370,21 @@ class RestfulTestCase(test_content_types.RestfulTestCase): """Make assertions common to all API responses.""" entity = resp.result.get(key) self.assertIsNotNone(entity) - self.assertValidEntity(entity, *args, **kwargs) + keys = kwargs.pop('keys_to_check', None) + self.assertValidEntity(entity, keys_to_check=keys, *args, **kwargs) entity_validator(entity, *args, **kwargs) return entity - def assertValidEntity(self, entity, ref=None): + def assertValidEntity(self, entity, ref=None, keys_to_check=None): """Make assertions common to all API entities. If a reference is provided, the entity will also be compared against the reference. """ - keys = ['name', 'description', 'enabled'] + if keys_to_check: + keys = keys_to_check + else: + keys = ['name', 'description', 'enabled'] for k in ['id'] + keys: msg = '%s unexpectedly None in %s' % (k, entity) @@ -439,9 +448,14 @@ class RestfulTestCase(test_content_types.RestfulTestCase): return token def assertValidScopedTokenResponse(self, r, *args, **kwargs): + require_catalog = kwargs.pop('require_catalog', True) token = self.assertValidTokenResponse(r, *args, **kwargs) - self.assertIn('catalog', token) + if require_catalog: + self.assertIn('catalog', token) + else: + self.assertNotIn('catalog', token) + self.assertIn('roles', token) self.assertTrue(token['roles']) for role in token['roles']: @@ -698,6 +712,7 @@ class RestfulTestCase(test_content_types.RestfulTestCase): resp, 'roles', self.assertValidRole, + keys_to_check=['name'], *args, **kwargs) @@ -706,6 +721,7 @@ class RestfulTestCase(test_content_types.RestfulTestCase): resp, 'role', self.assertValidRole, + keys_to_check=['name'], *args, **kwargs) @@ -715,6 +731,87 @@ class RestfulTestCase(test_content_types.RestfulTestCase): self.assertEqual(ref['name'], entity['name']) return entity + def assertValidRoleAssignmentListResponse(self, resp, ref=None, + expected_length=None): + + entities = resp.result.get('role_assignments') + + if expected_length is not None: + self.assertEqual(len(entities), expected_length) + elif ref is not None: + # we're at least expecting the ref + self.assertNotEmpty(entities) + + # collections should have relational links + self.assertValidListLinks(resp.result.get('links')) + + for entity in entities: + self.assertIsNotNone(entity) + self.assertValidRoleAssignment(entity) + if ref: + self.assertValidRoleAssignment(entity, ref) + return entities + + def assertValidRoleAssignment(self, entity, ref=None, url=None): + self.assertIsNotNone(entity.get('role')) + self.assertIsNotNone(entity.get('scope')) + + # Only one of user or group should be present + self.assertIsNotNone(entity.get('user') or + entity.get('group')) + self.assertIsNone(entity.get('user') and + entity.get('group')) + + # Only one of domain or project should be present + self.assertIsNotNone(entity['scope'].get('project') or + entity['scope'].get('domain')) + self.assertIsNone(entity['scope'].get('project') and + entity['scope'].get('domain')) + + if entity['scope'].get('project'): + self.assertIsNotNone(entity['scope']['project'].get('id')) + else: + self.assertIsNotNone(entity['scope']['domain'].get('id')) + self.assertIsNotNone(entity.get('links')) + self.assertIsNotNone(entity['links'].get('assignment')) + + if ref: + if ref.get('user'): + self.assertEqual(ref['user']['id'], entity['user']['id']) + if ref.get('group'): + self.assertEqual(ref['group']['id'], entity['group']['id']) + if ref.get('role'): + self.assertEqual(ref['role']['id'], entity['role']['id']) + if ref['scope'].get('project'): + self.assertEqual(ref['scope']['project']['id'], + entity['scope']['project']['id']) + if ref['scope'].get('domain'): + self.assertEqual(ref['scope']['domain']['id'], + entity['scope']['domain']['id']) + if url: + self.assertIn(url, entity['links']['assignment']) + + def assertRoleAssignmentInListResponse( + self, resp, ref, link_url=None, expected=1): + + found_count = 0 + for entity in resp.result.get('role_assignments'): + try: + self.assertValidRoleAssignment( + entity, ref=ref, url=link_url) + except Exception: + # It doesn't match, so let's go onto the next one + pass + else: + found_count += 1 + self.assertEqual(found_count, expected) + + def assertRoleAssignmentNotInListResponse( + self, resp, ref, link_url=None): + + self.assertRoleAssignmentInListResponse( + resp, ref=ref, link_url=link_url, expected=0) + # policy validation def assertValidPolicyListResponse(self, resp, *args, **kwargs): diff --git a/tests/test_v3_auth.py b/tests/test_v3_auth.py index a2bee8b8..11d66700 100644 --- a/tests/test_v3_auth.py +++ b/tests/test_v3_auth.py @@ -15,12 +15,11 @@ import json import uuid -import nose.exc - from keystone import auth from keystone.common import cms from keystone import config from keystone import exception +from keystone import test import test_v3 @@ -96,9 +95,14 @@ class TestAuthInfo(test_v3.RestfulTestCase): method_name) -class TestTokenAPIs(test_v3.RestfulTestCase): +class TestPKITokenAPIs(test_v3.RestfulTestCase): + def config_files(self): + conf_files = super(TestPKITokenAPIs, self).config_files() + conf_files.append(test.testsdir('test_pki_token_provider.conf')) + return conf_files + def setUp(self): - super(TestTokenAPIs, self).setUp() + super(TestPKITokenAPIs, self).setUp() auth_data = self.build_authentication_request( username=self.user['name'], user_domain_id=self.domain_id, @@ -111,8 +115,7 @@ class TestTokenAPIs(test_v3.RestfulTestCase): def test_default_fixture_scope_token(self): self.assertIsNotNone(self.get_scoped_token()) - def test_v3_pki_token_id(self): - self.opt_in_group('signing', token_format='PKI') + def test_v3_token_id(self): auth_data = self.build_authentication_request( user_id=self.user['id'], password=self.user['password']) @@ -120,13 +123,19 @@ class TestTokenAPIs(test_v3.RestfulTestCase): token_data = resp.result token_id = resp.headers.get('X-Subject-Token') self.assertIn('expires_at', token_data['token']) - token_signed = cms.cms_sign_token(json.dumps(token_data), - CONF.signing.certfile, - CONF.signing.keyfile) - self.assertEqual(token_signed, token_id) + + expected_token_id = cms.cms_sign_token(json.dumps(token_data), + CONF.signing.certfile, + CONF.signing.keyfile) + self.assertEqual(expected_token_id, token_id) + # should be able to validate hash PKI token as well + hash_token_id = cms.cms_hash_token(token_id) + headers = {'X-Subject-Token': hash_token_id} + resp = self.get('/auth/tokens', headers=headers) + expected_token_data = resp.result + self.assertDictEqual(expected_token_data, token_data) def test_v3_v2_intermix_non_default_domain_failed(self): - self.opt_in_group('signing', token_format='UUID') auth_data = self.build_authentication_request( user_id=self.user['id'], password=self.user['password']) @@ -141,7 +150,6 @@ class TestTokenAPIs(test_v3.RestfulTestCase): expected_status=401) def test_v3_v2_intermix_domain_scoped_token_failed(self): - self.opt_in_group('signing', token_format='UUID') # grant the domain role to user path = '/domains/%s/users/%s/roles/%s' % ( self.domain['id'], self.user['id'], self.role['id']) @@ -175,30 +183,7 @@ class TestTokenAPIs(test_v3.RestfulTestCase): method='GET', expected_status=401) - def test_v3_v2_unscoped_uuid_token_intermix(self): - self.opt_in_group('signing', token_format='UUID') - auth_data = self.build_authentication_request( - user_id=self.default_domain_user['id'], - password=self.default_domain_user['password']) - resp = self.post('/auth/tokens', body=auth_data) - token_data = resp.result - token = resp.headers.get('X-Subject-Token') - - # now validate the v3 token with v2 API - path = '/v2.0/tokens/%s' % (token) - resp = self.admin_request(path=path, - token='ADMIN', - method='GET') - v2_token = resp.result - self.assertEqual(v2_token['access']['user']['id'], - token_data['token']['user']['id']) - # v2 token time has not fraction of second precision so - # just need to make sure the non fraction part agrees - self.assertIn(v2_token['access']['token']['expires'][:-1], - token_data['token']['expires_at']) - - def test_v3_v2_unscoped_pki_token_intermix(self): - self.opt_in_group('signing', token_format='PKI') + def test_v3_v2_unscoped_token_intermix(self): auth_data = self.build_authentication_request( user_id=self.default_domain_user['id'], password=self.default_domain_user['password']) @@ -219,10 +204,9 @@ class TestTokenAPIs(test_v3.RestfulTestCase): self.assertIn(v2_token['access']['token']['expires'][:-1], token_data['token']['expires_at']) - def test_v3_v2_uuid_token_intermix(self): + def test_v3_v2_token_intermix(self): # FIXME(gyee): PKI tokens are not interchangeable because token # data is baked into the token itself. - self.opt_in_group('signing', token_format='UUID') auth_data = self.build_authentication_request( user_id=self.default_domain_user['id'], password=self.default_domain_user['password'], @@ -246,10 +230,7 @@ class TestTokenAPIs(test_v3.RestfulTestCase): self.assertEqual(v2_token['access']['user']['roles'][0]['id'], token_data['token']['roles'][0]['id']) - def test_v3_v2_pki_token_intermix(self): - # FIXME(gyee): PKI tokens are not interchangeable because token - # data is baked into the token itself. - self.opt_in_group('signing', token_format='PKI') + def test_v3_v2_hashed_pki_token_intermix(self): auth_data = self.build_authentication_request( user_id=self.default_domain_user['id'], password=self.default_domain_user['password'], @@ -258,7 +239,8 @@ class TestTokenAPIs(test_v3.RestfulTestCase): token_data = resp.result token = resp.headers.get('X-Subject-Token') - # now validate the v3 token with v2 API + # should be able to validate a hash PKI token in v2 too + token = cms.cms_hash_token(token) path = '/v2.0/tokens/%s' % (token) resp = self.admin_request(path=path, token='ADMIN', @@ -268,13 +250,12 @@ class TestTokenAPIs(test_v3.RestfulTestCase): token_data['token']['user']['id']) # v2 token time has not fraction of second precision so # just need to make sure the non fraction part agrees - self.assertIn(v2_token['access']['token']['expires'][-1], + self.assertIn(v2_token['access']['token']['expires'][:-1], token_data['token']['expires_at']) self.assertEqual(v2_token['access']['user']['roles'][0]['id'], token_data['token']['roles'][0]['id']) - def test_v2_v3_unscoped_uuid_token_intermix(self): - self.opt_in_group('signing', token_format='UUID') + def test_v2_v3_unscoped_token_intermix(self): body = { 'auth': { 'passwordCredentials': { @@ -297,59 +278,7 @@ class TestTokenAPIs(test_v3.RestfulTestCase): self.assertIn(v2_token_data['access']['token']['expires'][-1], token_data['token']['expires_at']) - def test_v2_v3_unscoped_pki_token_intermix(self): - self.opt_in_group('signing', token_format='PKI') - body = { - 'auth': { - 'passwordCredentials': { - 'userId': self.user['id'], - 'password': self.user['password'] - } - }} - resp = self.admin_request(path='/v2.0/tokens', - method='POST', - body=body) - v2_token_data = resp.result - v2_token = v2_token_data['access']['token']['id'] - headers = {'X-Subject-Token': v2_token} - resp = self.get('/auth/tokens', headers=headers) - token_data = resp.result - self.assertEqual(v2_token_data['access']['user']['id'], - token_data['token']['user']['id']) - # v2 token time has not fraction of second precision so - # just need to make sure the non fraction part agrees - self.assertIn(v2_token_data['access']['token']['expires'][-1], - token_data['token']['expires_at']) - - def test_v2_v3_uuid_token_intermix(self): - self.opt_in_group('signing', token_format='UUID') - body = { - 'auth': { - 'passwordCredentials': { - 'userId': self.user['id'], - 'password': self.user['password'] - }, - 'tenantId': self.project['id'] - }} - resp = self.admin_request(path='/v2.0/tokens', - method='POST', - body=body) - v2_token_data = resp.result - v2_token = v2_token_data['access']['token']['id'] - headers = {'X-Subject-Token': v2_token} - resp = self.get('/auth/tokens', headers=headers) - token_data = resp.result - self.assertEqual(v2_token_data['access']['user']['id'], - token_data['token']['user']['id']) - # v2 token time has not fraction of second precision so - # just need to make sure the non fraction part agrees - self.assertIn(v2_token_data['access']['token']['expires'][-1], - token_data['token']['expires_at']) - self.assertEqual(v2_token_data['access']['user']['roles'][0]['name'], - token_data['token']['roles'][0]['name']) - - def test_v2_v3_pki_token_intermix(self): - self.opt_in_group('signing', token_format='PKI') + def test_v2_v3_token_intermix(self): body = { 'auth': { 'passwordCredentials': { @@ -402,6 +331,28 @@ class TestTokenAPIs(test_v3.RestfulTestCase): self.assertIn('signed', r.result) +class TestUUIDTokenAPIs(TestPKITokenAPIs): + def config_files(self): + conf_files = super(TestUUIDTokenAPIs, self).config_files() + conf_files.append(test.testsdir('test_uuid_token_provider.conf')) + return conf_files + + def test_v3_token_id(self): + auth_data = self.build_authentication_request( + user_id=self.user['id'], + password=self.user['password']) + resp = self.post('/auth/tokens', body=auth_data) + token_data = resp.result + token_id = resp.headers.get('X-Subject-Token') + self.assertIn('expires_at', token_data['token']) + self.assertFalse(cms.is_ans1_token(token_id)) + + def test_v3_v2_hashed_pki_token_intermix(self): + # this test is only applicable for PKI tokens + # skipping it for UUID tokens + pass + + class TestTokenRevoking(test_v3.RestfulTestCase): """Test token revocation on the v3 Identity API.""" @@ -793,6 +744,66 @@ class TestTokenRevoking(test_v3.RestfulTestCase): project_id=self.projectA['id'])) +class TestAuthExternalDisabled(test_v3.RestfulTestCase): + def config_files(self): + list = self._config_file_list[:] + list.append('auth_plugin_external_disabled.conf') + return list + + def test_remote_user_disabled(self): + auth_data = self.build_authentication_request()['auth'] + api = auth.controllers.Auth() + context = {'REMOTE_USER': '%s@%s' % (self.user['name'], + self.domain['id'])} + auth_info = auth.controllers.AuthInfo(None, auth_data) + auth_context = {'extras': {}, 'method_names': []} + self.assertRaises(exception.Unauthorized, + api.authenticate, + context, + auth_info, + auth_context) + + +class TestAuthExternalDomain(test_v3.RestfulTestCase): + content_type = 'json' + + def config_files(self): + list = self._config_file_list[:] + list.append('auth_plugin_external_domain.conf') + return list + + def test_remote_user_with_realm(self): + auth_data = self.build_authentication_request()['auth'] + api = auth.controllers.Auth() + context = {'REMOTE_USER': '%s@%s' % + (self.user['name'], self.domain['name'])} + auth_info = auth.controllers.AuthInfo(None, auth_data) + auth_context = {'extras': {}, 'method_names': []} + api.authenticate(context, auth_info, auth_context) + self.assertEqual(auth_context['user_id'], self.user['id']) + + def test_project_id_scoped_with_remote_user(self): + CONF.token.bind = ['kerberos'] + auth_data = self.build_authentication_request( + project_id=self.project['id']) + remote_user = '%s@%s' % (self.user['name'], self.domain['name']) + self.admin_app.extra_environ.update({'REMOTE_USER': remote_user, + 'AUTH_TYPE': 'Negotiate'}) + r = self.post('/auth/tokens', body=auth_data) + token = self.assertValidProjectScopedTokenResponse(r) + self.assertEquals(token['bind']['kerberos'], self.user['name']) + + def test_unscoped_bind_with_remote_user(self): + CONF.token.bind = ['kerberos'] + auth_data = self.build_authentication_request() + remote_user = '%s@%s' % (self.user['name'], self.domain['name']) + self.admin_app.extra_environ.update({'REMOTE_USER': remote_user, + 'AUTH_TYPE': 'Negotiate'}) + r = self.post('/auth/tokens', body=auth_data) + token = self.assertValidUnscopedTokenResponse(r) + self.assertEquals(token['bind']['kerberos'], self.user['name']) + + class TestAuthJSON(test_v3.RestfulTestCase): content_type = 'json' @@ -855,6 +866,45 @@ class TestAuthJSON(test_v3.RestfulTestCase): self.assertValidProjectScopedTokenResponse(r) self.assertEqual(r.result['token']['project']['id'], project['id']) + def test_default_project_id_scoped_token_with_user_id_no_catalog(self): + # create a second project to work with + ref = self.new_project_ref(domain_id=self.domain_id) + r = self.post('/projects', body={'project': ref}) + project = self.assertValidProjectResponse(r, ref) + + # grant the user a role on the project + self.put( + '/projects/%(project_id)s/users/%(user_id)s/roles/%(role_id)s' % { + 'user_id': self.user['id'], + 'project_id': project['id'], + 'role_id': self.role['id']}) + + # set the user's preferred project + body = {'user': {'default_project_id': project['id']}} + r = self.patch('/users/%(user_id)s' % { + 'user_id': self.user['id']}, + body=body) + self.assertValidUserResponse(r) + + # attempt to authenticate without requesting a project + auth_data = self.build_authentication_request( + user_id=self.user['id'], + password=self.user['password']) + r = self.post('/auth/tokens?nocatalog', body=auth_data) + self.assertValidProjectScopedTokenResponse(r, require_catalog=False) + self.assertEqual(r.result['token']['project']['id'], project['id']) + + def test_implicit_project_id_scoped_token_with_user_id_no_catalog(self): + # attempt to authenticate without requesting a project + auth_data = self.build_authentication_request( + user_id=self.user['id'], + password=self.user['password'], + project_id=self.project['id']) + r = self.post('/auth/tokens?nocatalog', body=auth_data) + self.assertValidProjectScopedTokenResponse(r, require_catalog=False) + self.assertEqual(r.result['token']['project']['id'], + self.project['id']) + def test_default_project_id_scoped_token_with_user_id_401(self): # create a second project to work with ref = self.new_project_ref(domain_id=self.domain['id']) @@ -888,6 +938,137 @@ class TestAuthJSON(test_v3.RestfulTestCase): project_id=project['id']) self.post('/auth/tokens', body=auth_data, expected_status=401) + def test_user_and_group_roles_scoped_token(self): + """Test correct roles are returned in scoped token. + + Test Plan: + - Create a domain, with 1 project, 2 users (user1 and user2) + and 2 groups (group1 and group2) + - Make user1 a member of group1, user2 a member of group2 + - Create 8 roles, assigning them to each of the 8 combinations + of users/groups on domain/project + - Get a project scoped token for user1, checking that the right + two roles are returned (one directly assigned, one by virtue + of group membership) + - Repeat this for a domain scoped token + - Make user1 also a member of group2 + - Get another scoped token making sure the additional role + shows up + - User2 is just here as a spoiler, to make sure we don't get + any roles uniquely assigned to it returned in any of our + tokens + + """ + + domainA = self.new_domain_ref() + self.identity_api.create_domain(domainA['id'], domainA) + projectA = self.new_project_ref(domain_id=domainA['id']) + self.identity_api.create_project(projectA['id'], projectA) + + user1 = self.new_user_ref( + domain_id=domainA['id']) + user1['password'] = uuid.uuid4().hex + self.identity_api.create_user(user1['id'], user1) + + user2 = self.new_user_ref( + domain_id=domainA['id']) + user2['password'] = uuid.uuid4().hex + self.identity_api.create_user(user2['id'], user2) + + group1 = self.new_group_ref( + domain_id=domainA['id']) + self.identity_api.create_group(group1['id'], group1) + + group2 = self.new_group_ref( + domain_id=domainA['id']) + self.identity_api.create_group(group2['id'], group2) + + self.identity_api.add_user_to_group(user1['id'], + group1['id']) + self.identity_api.add_user_to_group(user2['id'], + group2['id']) + + # Now create all the roles and assign them + role_list = [] + for _ in range(8): + role = self.new_role_ref() + self.identity_api.create_role(role['id'], role) + role_list.append(role) + + self.identity_api.create_grant(role_list[0]['id'], + user_id=user1['id'], + domain_id=domainA['id']) + self.identity_api.create_grant(role_list[1]['id'], + user_id=user1['id'], + project_id=projectA['id']) + self.identity_api.create_grant(role_list[2]['id'], + user_id=user2['id'], + domain_id=domainA['id']) + self.identity_api.create_grant(role_list[3]['id'], + user_id=user2['id'], + project_id=projectA['id']) + self.identity_api.create_grant(role_list[4]['id'], + group_id=group1['id'], + domain_id=domainA['id']) + self.identity_api.create_grant(role_list[5]['id'], + group_id=group1['id'], + project_id=projectA['id']) + self.identity_api.create_grant(role_list[6]['id'], + group_id=group2['id'], + domain_id=domainA['id']) + self.identity_api.create_grant(role_list[7]['id'], + group_id=group2['id'], + project_id=projectA['id']) + + # First, get a project scoped token - which should + # contain the direct user role and the one by virtue + # of group membership + auth_data = self.build_authentication_request( + user_id=user1['id'], + password=user1['password'], + project_id=projectA['id']) + r = self.post('/auth/tokens', body=auth_data) + token = self.assertValidScopedTokenResponse(r) + roles_ids = [] + for i, ref in enumerate(token['roles']): + roles_ids.append(ref['id']) + self.assertEqual(len(token['roles']), 2) + self.assertIn(role_list[1]['id'], roles_ids) + self.assertIn(role_list[5]['id'], roles_ids) + + # Now the same thing for a domain scoped token + auth_data = self.build_authentication_request( + user_id=user1['id'], + password=user1['password'], + domain_id=domainA['id']) + r = self.post('/auth/tokens', body=auth_data) + token = self.assertValidScopedTokenResponse(r) + roles_ids = [] + for i, ref in enumerate(token['roles']): + roles_ids.append(ref['id']) + self.assertEqual(len(token['roles']), 2) + self.assertIn(role_list[0]['id'], roles_ids) + self.assertIn(role_list[4]['id'], roles_ids) + + # Finally, add user1 to the 2nd group, and get a new + # scoped token - the extra role should now be included + # by virtue of the 2nd group + self.identity_api.add_user_to_group(user1['id'], + group2['id']) + auth_data = self.build_authentication_request( + user_id=user1['id'], + password=user1['password'], + project_id=projectA['id']) + r = self.post('/auth/tokens', body=auth_data) + token = self.assertValidScopedTokenResponse(r) + roles_ids = [] + for i, ref in enumerate(token['roles']): + roles_ids.append(ref['id']) + self.assertEqual(len(token['roles']), 3) + self.assertIn(role_list[1]['id'], roles_ids) + self.assertIn(role_list[5]['id'], roles_ids) + self.assertIn(role_list[7]['id'], roles_ids) + def test_project_id_scoped_token_with_user_domain_id(self): auth_data = self.build_authentication_request( username=self.user['name'], @@ -1072,31 +1253,155 @@ class TestAuthJSON(test_v3.RestfulTestCase): password=uuid.uuid4().hex) self.post('/auth/tokens', body=auth_data, expected_status=401) - def test_remote_user(self): + def test_remote_user_no_realm(self): + CONF.auth.methods = 'external' + api = auth.controllers.Auth() + auth_data = self.build_authentication_request()['auth'] + context = {'REMOTE_USER': self.default_domain_user['name']} + auth_info = auth.controllers.AuthInfo(None, auth_data) + auth_context = {'extras': {}, 'method_names': []} + api.authenticate(context, auth_info, auth_context) + self.assertEqual(auth_context['user_id'], + self.default_domain_user['id']) + + def test_remote_user_no_domain(self): + auth_data = self.build_authentication_request()['auth'] + api = auth.controllers.Auth() + context = {'REMOTE_USER': self.user['name']} + auth_info = auth.controllers.AuthInfo(None, auth_data) + auth_context = {'extras': {}, 'method_names': []} + self.assertRaises(exception.Unauthorized, + api.authenticate, + context, + auth_info, + auth_context) + + def test_remote_user_and_password(self): + #both REMOTE_USER and password methods must pass. + #note that they do not have to match auth_data = self.build_authentication_request( - user_id=self.user['id'], + user_domain_id=self.domain['id'], + username=self.user['name'], password=self.user['password'])['auth'] api = auth.controllers.Auth() - context = {'REMOTE_USER': self.user['name']} + context = {'REMOTE_USER': self.default_domain_user['name']} auth_info = auth.controllers.AuthInfo(None, auth_data) auth_context = {'extras': {}, 'method_names': []} api.authenticate(context, auth_info, auth_context) - self.assertEqual(auth_context['user_id'], self.user['id']) - def test_remote_user_no_domain(self): + def test_remote_user_and_explicit_external(self): + #both REMOTE_USER and password methods must pass. + #note that they do not have to match auth_data = self.build_authentication_request( + user_domain_id=self.domain['id'], username=self.user['name'], password=self.user['password'])['auth'] + auth_data['identity']['methods'] = ["password", "external"] + auth_data['identity']['external'] = {} api = auth.controllers.Auth() - context = {'REMOTE_USER': self.user['name']} + context = {} auth_info = auth.controllers.AuthInfo(None, auth_data) auth_context = {'extras': {}, 'method_names': []} - self.assertRaises(exception.ValidationError, + self.assertRaises(exception.Unauthorized, api.authenticate, context, auth_info, auth_context) + def test_remote_user_bad_password(self): + #both REMOTE_USER and password methods must pass. + auth_data = self.build_authentication_request( + user_domain_id=self.domain['id'], + username=self.user['name'], + password='badpassword')['auth'] + api = auth.controllers.Auth() + context = {'REMOTE_USER': self.default_domain_user['name']} + auth_info = auth.controllers.AuthInfo(None, auth_data) + auth_context = {'extras': {}, 'method_names': []} + self.assertRaises(exception.Unauthorized, + api.authenticate, + context, + auth_info, + auth_context) + + def test_bind_not_set_with_remote_user(self): + CONF.token.bind = [] + auth_data = self.build_authentication_request() + remote_user = self.default_domain_user['name'] + self.admin_app.extra_environ.update({'REMOTE_USER': remote_user, + 'AUTH_TYPE': 'Negotiate'}) + r = self.post('/auth/tokens', body=auth_data) + token = self.assertValidUnscopedTokenResponse(r) + self.assertNotIn('bind', token) + + #TODO(ayoung): move to TestPKITokenAPIs; it will be run for both formats + def test_verify_with_bound_token(self): + self.opt_in_group('token', bind='kerberos') + auth_data = self.build_authentication_request( + project_id=self.project['id']) + remote_user = self.default_domain_user['name'] + self.admin_app.extra_environ.update({'REMOTE_USER': remote_user, + 'AUTH_TYPE': 'Negotiate'}) + + resp = self.post('/auth/tokens', body=auth_data) + + token = resp.headers.get('X-Subject-Token') + headers = {'X-Subject-Token': token} + r = self.get('/auth/tokens', headers=headers, token=token) + token = self.assertValidProjectScopedTokenResponse(r) + self.assertEqual(token['bind']['kerberos'], + self.default_domain_user['name']) + + def test_auth_with_bind_token(self): + CONF.token.bind = ['kerberos'] + + auth_data = self.build_authentication_request() + remote_user = self.default_domain_user['name'] + self.admin_app.extra_environ.update({'REMOTE_USER': remote_user, + 'AUTH_TYPE': 'Negotiate'}) + r = self.post('/auth/tokens', body=auth_data) + + # the unscoped token should have bind information in it + token = self.assertValidUnscopedTokenResponse(r) + self.assertEqual(token['bind']['kerberos'], remote_user) + + token = r.headers.get('X-Subject-Token') + + # using unscoped token with remote user succeeds + auth_params = {'token': token, 'project_id': self.project_id} + auth_data = self.build_authentication_request(**auth_params) + r = self.post('/auth/tokens', body=auth_data) + token = self.assertValidProjectScopedTokenResponse(r) + + # the bind information should be carried over from the original token + self.assertEqual(token['bind']['kerberos'], remote_user) + + def test_v2_v3_bind_token_intermix(self): + self.opt_in_group('token', bind='kerberos') + + # we need our own user registered to the default domain because of + # the way external auth works. + remote_user = self.default_domain_user['name'] + self.admin_app.extra_environ.update({'REMOTE_USER': remote_user, + 'AUTH_TYPE': 'Negotiate'}) + body = {'auth': {}} + resp = self.admin_request(path='/v2.0/tokens', + method='POST', + body=body) + + v2_token_data = resp.result + + bind = v2_token_data['access']['token']['bind'] + self.assertEqual(bind['kerberos'], self.default_domain_user['name']) + + v2_token_id = v2_token_data['access']['token']['id'] + headers = {'X-Subject-Token': v2_token_id} + resp = self.get('/auth/tokens', headers=headers) + token_data = resp.result + + self.assertDictEqual(v2_token_data['access']['token']['bind'], + token_data['token']['bind']) + class TestAuthXML(TestAuthJSON): content_type = 'xml' @@ -1131,7 +1436,7 @@ class TestTrustAuth(TestAuthInfo): self.identity_api.create_user(self.trustee_user_id, self.trustee_user) def test_create_trust_400(self): - raise nose.exc.SkipTest('Blocked by bug 1133435') + self.skipTest('Blocked by bug 1133435') self.post('/OS-TRUST/trusts', body={'trust': {}}, expected_status=400) def test_create_unscoped_trust(self): diff --git a/tests/test_v3_identity.py b/tests/test_v3_identity.py index 1e10070e..f1e19c42 100644 --- a/tests/test_v3_identity.py +++ b/tests/test_v3_identity.py @@ -16,11 +16,64 @@ import uuid +from keystone import config from keystone import exception import test_v3 +def _build_role_assignment_url_and_entity( + role_id, user_id=None, group_id=None, domain_id=None, + project_id=None, inherited_to_projects=False, + effective=False): + + if user_id and domain_id: + url = ('/domains/%(domain_id)s/users/%(user_id)s' + '/roles/%(role_id)s' % { + 'domain_id': domain_id, + 'user_id': user_id, + 'role_id': role_id}) + entity = {'role': {'id': role_id}, + 'user': {'id': user_id}, + 'scope': {'domain': {'id': domain_id}}} + if inherited_to_projects: + url = '/OS-INHERIT%s/inherited_to_projects' % url + if not effective: + entity['OS-INHERIT:inherited_to'] = 'projects' + elif user_id and project_id: + url = ('/projects/%(project_id)s/users/%(user_id)s' + '/roles/%(role_id)s' % { + 'project_id': project_id, + 'user_id': user_id, + 'role_id': role_id}) + entity = {'role': {'id': role_id}, + 'user': {'id': user_id}, + 'scope': {'project': {'id': project_id}}} + if group_id and domain_id: + url = ('/domains/%(domain_id)s/groups/%(group_id)s' + '/roles/%(role_id)s' % { + 'domain_id': domain_id, + 'group_id': group_id, + 'role_id': role_id}) + entity = {'role': {'id': role_id}, + 'group': {'id': group_id}, + 'scope': {'domain': {'id': domain_id}}} + if inherited_to_projects: + url = '/OS-INHERIT%s/inherited_to_projects' % url + if not effective: + entity['OS-INHERIT:inherited_to'] = 'projects' + elif group_id and project_id: + url = ('/projects/%(project_id)s/groups/%(group_id)s' + '/roles/%(role_id)s' % { + 'project_id': project_id, + 'group_id': group_id, + 'role_id': role_id}) + entity = {'role': {'id': role_id}, + 'group': {'id': group_id}, + 'scope': {'project': {'id': project_id}}} + return (url, entity) + + class IdentityTestCase(test_v3.RestfulTestCase): """Test domains, projects, users, groups, & role CRUD.""" @@ -52,6 +105,10 @@ class IdentityTestCase(test_v3.RestfulTestCase): body={'domain': ref}) return self.assertValidDomainResponse(r, ref) + def test_create_domain_400(self): + """Call ``POST /domains``.""" + self.post('/domains', body={'domain': {}}, expected_status=400) + def test_list_domains(self): """Call ``GET /domains``.""" r = self.get('/domains') @@ -213,19 +270,19 @@ class IdentityTestCase(test_v3.RestfulTestCase): # Check all the domain2 relevant entities are gone self.assertRaises(exception.DomainNotFound, self.identity_api.get_domain, - domain_id=self.domain2['id']) + self.domain2['id']) self.assertRaises(exception.ProjectNotFound, self.identity_api.get_project, - tenant_id=self.project2['id']) + self.project2['id']) self.assertRaises(exception.GroupNotFound, self.identity_api.get_group, - group_id=self.group2['id']) + self.group2['id']) self.assertRaises(exception.UserNotFound, self.identity_api.get_user, - user_id=self.user2['id']) + self.user2['id']) self.assertRaises(exception.CredentialNotFound, self.credential_api.get_credential, - credential_id=self.credential2['id']) + self.credential2['id']) # ...and that all self.domain entities are still here r = self.identity_api.get_domain(self.domain['id']) @@ -260,6 +317,10 @@ class IdentityTestCase(test_v3.RestfulTestCase): body={'project': ref}) self.assertValidProjectResponse(r, ref) + def test_create_project_400(self): + """Call ``POST /projects``.""" + self.post('/projects', body={'project': {}}, expected_status=400) + def test_get_project(self): """Call ``GET /projects/{project_id}``.""" r = self.get( @@ -323,6 +384,10 @@ class IdentityTestCase(test_v3.RestfulTestCase): body={'user': ref}) return self.assertValidUserResponse(r, ref) + def test_create_user_400(self): + """Call ``POST /users``.""" + self.post('/users', body={'user': {}}, expected_status=400) + def test_list_users(self): """Call ``GET /users``.""" r = self.get('/users') @@ -458,7 +523,7 @@ class IdentityTestCase(test_v3.RestfulTestCase): # that reference this project self.assertRaises(exception.CredentialNotFound, self.credential_api.get_credential, - credential_id=self.credential['id']) + self.credential['id']) # And the no tokens we remain valid tokens = self.token_api.list_tokens(self.user['id']) self.assertEquals(len(tokens), 0) @@ -476,6 +541,10 @@ class IdentityTestCase(test_v3.RestfulTestCase): body={'group': ref}) return self.assertValidGroupResponse(r, ref) + def test_create_group_400(self): + """Call ``POST /groups``.""" + self.post('/groups', body={'group': {}}, expected_status=400) + def test_list_groups(self): """Call ``GET /groups``.""" r = self.get('/groups') @@ -516,6 +585,10 @@ class IdentityTestCase(test_v3.RestfulTestCase): body={'role': ref}) return self.assertValidRoleResponse(r, ref) + def test_create_role_400(self): + """Call ``POST /roles``.""" + self.post('/roles', body={'role': {}}, expected_status=400) + def test_list_roles(self): """Call ``GET /roles``.""" r = self.get('/roles') @@ -627,3 +700,858 @@ class IdentityTestCase(test_v3.RestfulTestCase): r = self.get(collection_url) self.assertValidRoleListResponse(r, expected_length=0) self.assertIn(collection_url, r.result['links']['self']) + + def test_get_role_assignments(self): + """Call ``GET /role_assignments``. + + The sample data set up already has a user, group and project + that is part of self.domain. We use these plus a new user + we create as our data set, making sure we ignore any + role assignments that are already in existence. + + Since we don't yet support a first class entity for role + assignments, we are only testing the LIST API. To create + and delete the role assignments we use the old grant APIs. + + Test Plan: + - Create extra user for tests + - Get a list of all existing role assignments + - Add a new assignment for each of the four combinations, i.e. + group+domain, user+domain, group+project, user+project, using + the same role each time + - Get a new list of all role assignments, checking these four new + ones have been added + - Then delete the four we added + - Get a new list of all role assignments, checking the four have + been removed + + """ + + # Since the default fixtures already assign some roles to the + # user it creates, we also need a new user that will not have any + # existing assignments + self.user1 = self.new_user_ref( + domain_id=self.domain['id']) + self.user1['password'] = uuid.uuid4().hex + self.identity_api.create_user(self.user1['id'], self.user1) + + collection_url = '/role_assignments' + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertIn(collection_url, r.result['links']['self']) + existing_assignments = len(r.result.get('role_assignments')) + + # Now add one of each of the four types of assignment, making sure + # that we get them all back. + gd_url, gd_entity = _build_role_assignment_url_and_entity( + domain_id=self.domain_id, group_id=self.group_id, + role_id=self.role_id) + self.put(gd_url) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), + existing_assignments + 1) + self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) + + ud_url, ud_entity = _build_role_assignment_url_and_entity( + domain_id=self.domain_id, user_id=self.user1['id'], + role_id=self.role_id) + self.put(ud_url) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), + existing_assignments + 2) + self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=ud_url) + + gp_url, gp_entity = _build_role_assignment_url_and_entity( + project_id=self.project_id, group_id=self.group_id, + role_id=self.role_id) + self.put(gp_url) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), + existing_assignments + 3) + self.assertRoleAssignmentInListResponse(r, gp_entity, link_url=gp_url) + + up_url, up_entity = _build_role_assignment_url_and_entity( + project_id=self.project_id, user_id=self.user1['id'], + role_id=self.role_id) + self.put(up_url) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), + existing_assignments + 4) + self.assertRoleAssignmentInListResponse(r, up_entity, link_url=up_url) + + # Now delete the four we added and make sure they are removed + # from the collection. + + self.delete(gd_url) + self.delete(ud_url) + self.delete(gp_url) + self.delete(up_url) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), + existing_assignments) + self.assertRoleAssignmentNotInListResponse(r, gd_entity) + self.assertRoleAssignmentNotInListResponse(r, ud_entity) + self.assertRoleAssignmentNotInListResponse(r, gp_entity) + self.assertRoleAssignmentNotInListResponse(r, up_entity) + + def test_get_effective_role_assignments(self): + """Call ``GET /role_assignments?effective``. + + Test Plan: + - Create two extra user for tests + - Add these users to a group + - Add a role assignment for the group on a domain + - Get a list of all role assignments, checking one has been added + - Then get a list of all effective role assignments - the group + assignment should have turned into assignments on the domain + for each of the group members. + + """ + self.user1 = self.new_user_ref( + domain_id=self.domain['id']) + self.user1['password'] = uuid.uuid4().hex + self.identity_api.create_user(self.user1['id'], self.user1) + self.user2 = self.new_user_ref( + domain_id=self.domain['id']) + self.user2['password'] = uuid.uuid4().hex + self.identity_api.create_user(self.user2['id'], self.user2) + self.identity_api.add_user_to_group(self.user1['id'], self.group['id']) + self.identity_api.add_user_to_group(self.user2['id'], self.group['id']) + + collection_url = '/role_assignments' + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertIn(collection_url, r.result['links']['self']) + existing_assignments = len(r.result.get('role_assignments')) + + gd_url, gd_entity = _build_role_assignment_url_and_entity( + domain_id=self.domain_id, group_id=self.group_id, + role_id=self.role_id) + self.put(gd_url) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), + existing_assignments + 1) + self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) + + # Now re-read the collection asking for effective roles - this + # should mean the group assignment is translated into the two + # member user assignments + collection_url = '/role_assignments?effective' + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), + existing_assignments + 2) + unused, ud_entity = _build_role_assignment_url_and_entity( + domain_id=self.domain_id, user_id=self.user1['id'], + role_id=self.role_id) + gd_url, unused = _build_role_assignment_url_and_entity( + domain_id=self.domain_id, group_id=self.group['id'], + role_id=self.role_id) + self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=gd_url) + ud_url, ud_entity = _build_role_assignment_url_and_entity( + domain_id=self.domain_id, user_id=self.user2['id'], + role_id=self.role_id) + self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=gd_url) + + def test_check_effective_values_for_role_assignments(self): + """Call ``GET /role_assignments?effective=value``. + + Check the various ways of specifying the 'effective' + query parameter. If the 'effective' query parameter + is included then this should always be treated as + as meaning 'True' unless it is specified as: + + {url}?effective=0 + + This is by design to match the agreed way of handling + policy checking on query/filter parameters. + + Test Plan: + - Create two extra user for tests + - Add these users to a group + - Add a role assignment for the group on a domain + - Get a list of all role assignments, checking one has been added + - Then issue various request with different ways of defining + the 'effective' query parameter. As we have tested the + correctness of the data coming back when we get effective roles + in other tests, here we just use the count of entities to + know if we are getting effective roles or not + + """ + self.user1 = self.new_user_ref( + domain_id=self.domain['id']) + self.user1['password'] = uuid.uuid4().hex + self.identity_api.create_user(self.user1['id'], self.user1) + self.user2 = self.new_user_ref( + domain_id=self.domain['id']) + self.user2['password'] = uuid.uuid4().hex + self.identity_api.create_user(self.user2['id'], self.user2) + self.identity_api.add_user_to_group(self.user1['id'], self.group['id']) + self.identity_api.add_user_to_group(self.user2['id'], self.group['id']) + + collection_url = '/role_assignments' + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + existing_assignments = len(r.result.get('role_assignments')) + + gd_url, gd_entity = _build_role_assignment_url_and_entity( + domain_id=self.domain_id, group_id=self.group_id, + role_id=self.role_id) + self.put(gd_url) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), + existing_assignments + 1) + self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) + + # Now re-read the collection asking for effective roles, + # using the most common way of defining "effective'. This + # should mean the group assignment is translated into the two + # member user assignments + collection_url = '/role_assignments?effective' + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), + existing_assignments + 2) + # Now set 'effective' to false explicitly - should get + # back the regular roles + collection_url = '/role_assignments?effective=0' + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), + existing_assignments + 1) + # Now try setting 'effective' to 'False' explicitly- this is + # NOT supported as a way of setting a query or filter + # parameter to false by design. Hence we should get back + # effective roles. + collection_url = '/role_assignments?effective=False' + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), + existing_assignments + 2) + # Now set 'effective' to True explicitly + collection_url = '/role_assignments?effective=True' + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), + existing_assignments + 2) + + def test_filtered_role_assignments(self): + """Call ``GET /role_assignments?filters``. + + Test Plan: + - Create extra users, group, role and project for tests + - Make the following assignments: + Give group1, role1 on project1 and domain + Give user1, role2 on project1 and domain + Make User1 a member of Group1 + - Test a series of single filter list calls, checking that + the correct results are obtained + - Test a multi-filtered list call + - Test listing all effective roles for a given user + - Test the equivalent of the list of roles in a project scoped + token (all effective roles for a user on a project) + + """ + + # Since the default fixtures already assign some roles to the + # user it creates, we also need a new user that will not have any + # existing assignments + self.user1 = self.new_user_ref( + domain_id=self.domain['id']) + self.user1['password'] = uuid.uuid4().hex + self.identity_api.create_user(self.user1['id'], self.user1) + self.user2 = self.new_user_ref( + domain_id=self.domain['id']) + self.user2['password'] = uuid.uuid4().hex + self.identity_api.create_user(self.user2['id'], self.user2) + self.group1 = self.new_group_ref( + domain_id=self.domain['id']) + self.identity_api.create_group(self.group1['id'], self.group1) + self.identity_api.add_user_to_group(self.user1['id'], + self.group1['id']) + self.identity_api.add_user_to_group(self.user2['id'], + self.group1['id']) + self.project1 = self.new_project_ref( + domain_id=self.domain['id']) + self.identity_api.create_project(self.project1['id'], self.project1) + self.role1 = self.new_role_ref() + self.identity_api.create_role(self.role1['id'], self.role1) + self.role2 = self.new_role_ref() + self.identity_api.create_role(self.role2['id'], self.role2) + + # Now add one of each of the four types of assignment + + gd_url, gd_entity = _build_role_assignment_url_and_entity( + domain_id=self.domain_id, group_id=self.group1['id'], + role_id=self.role1['id']) + self.put(gd_url) + + ud_url, ud_entity = _build_role_assignment_url_and_entity( + domain_id=self.domain_id, user_id=self.user1['id'], + role_id=self.role2['id']) + self.put(ud_url) + + gp_url, gp_entity = _build_role_assignment_url_and_entity( + project_id=self.project1['id'], group_id=self.group1['id'], + role_id=self.role1['id']) + self.put(gp_url) + + up_url, up_entity = _build_role_assignment_url_and_entity( + project_id=self.project1['id'], user_id=self.user1['id'], + role_id=self.role2['id']) + self.put(up_url) + + # Now list by various filters to make sure we get back the right ones + + collection_url = ('/role_assignments?scope.project.id=%s' % + self.project1['id']) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), 2) + self.assertRoleAssignmentInListResponse(r, up_entity, link_url=up_url) + self.assertRoleAssignmentInListResponse(r, gp_entity, link_url=gp_url) + + collection_url = ('/role_assignments?scope.domain.id=%s' % + self.domain['id']) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), 2) + self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=ud_url) + self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) + + collection_url = '/role_assignments?user.id=%s' % self.user1['id'] + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), 2) + self.assertRoleAssignmentInListResponse(r, up_entity, link_url=up_url) + self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=ud_url) + + collection_url = '/role_assignments?group.id=%s' % self.group1['id'] + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), 2) + self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) + self.assertRoleAssignmentInListResponse(r, gp_entity, link_url=gp_url) + + collection_url = '/role_assignments?role.id=%s' % self.role1['id'] + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), 2) + self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) + self.assertRoleAssignmentInListResponse(r, gp_entity, link_url=gp_url) + + # Let's try combining two filers together.... + + collection_url = ( + '/role_assignments?user.id=%(user_id)s' + '&scope.project.id=%(project_id)s' % { + 'user_id': self.user1['id'], + 'project_id': self.project1['id']}) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), 1) + self.assertRoleAssignmentInListResponse(r, up_entity, link_url=up_url) + + # Now for a harder one - filter for user with effective + # roles - this should return role assignment that were directly + # assigned as well as by virtue of group membership + + collection_url = ('/role_assignments?effective&user.id=%s' % + self.user1['id']) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), 4) + # Should have the two direct roles... + self.assertRoleAssignmentInListResponse(r, up_entity, link_url=up_url) + self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=ud_url) + # ...and the two via group membership... + unused, up1_entity = _build_role_assignment_url_and_entity( + project_id=self.project1['id'], user_id=self.user1['id'], + role_id=self.role1['id']) + unused, ud1_entity = _build_role_assignment_url_and_entity( + domain_id=self.domain_id, user_id=self.user1['id'], + role_id=self.role1['id']) + gp1_url, unused = _build_role_assignment_url_and_entity( + project_id=self.project1['id'], group_id=self.group1['id'], + role_id=self.role1['id']) + gd1_url, unused = _build_role_assignment_url_and_entity( + domain_id=self.domain_id, group_id=self.group1['id'], + role_id=self.role1['id']) + self.assertRoleAssignmentInListResponse(r, up1_entity, + link_url=gp1_url) + self.assertRoleAssignmentInListResponse(r, ud1_entity, + link_url=gd1_url) + + # ...and for the grand-daddy of them all, simulate the request + # that would generate the list of effective roles in a project + # scoped token. + + collection_url = ( + '/role_assignments?effective&user.id=%(user_id)s' + '&scope.project.id=%(project_id)s' % { + 'user_id': self.user1['id'], + 'project_id': self.project1['id']}) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), 2) + # Should have one direct role and one from group membership... + self.assertRoleAssignmentInListResponse(r, up_entity, link_url=up_url) + self.assertRoleAssignmentInListResponse(r, up1_entity, + link_url=gp1_url) + + +class IdentityIneritanceTestCase(test_v3.RestfulTestCase): + """Test inheritance crud and its effects.""" + + def setUp(self): + self.orig_extension_enablement = config.CONF.os_inherit.enabled + self.opt_in_group('os_inherit', enabled=True) + super(IdentityIneritanceTestCase, self).setUp() + + def tearDown(self): + super(IdentityIneritanceTestCase, self).tearDown() + self.opt_in_group('os_inherit', enabled=self.orig_extension_enablement) + + def test_crud_user_inherited_domain_role_grants(self): + role_list = [] + for _ in range(2): + role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.assignment_api.create_role(role['id'], role) + role_list.append(role) + + # Create a non-inherited role as a spoiler + self.assignment_api.create_grant( + role_list[1]['id'], user_id=self.user['id'], + domain_id=self.domain_id) + + base_collection_url = ( + '/OS-INHERIT/domains/%(domain_id)s/users/%(user_id)s/roles' % { + 'domain_id': self.domain_id, + 'user_id': self.user['id']}) + member_url = '%(collection_url)s/%(role_id)s/inherited_to_projects' % { + 'collection_url': base_collection_url, + 'role_id': role_list[0]['id']} + collection_url = base_collection_url + '/inherited_to_projects' + + self.put(member_url) + + # Check we can read it back + self.head(member_url) + r = self.get(collection_url) + self.assertValidRoleListResponse(r, ref=role_list[0]) + self.assertIn(collection_url, r.result['links']['self']) + + # Now delete and check its gone + self.delete(member_url) + r = self.get(collection_url) + self.assertValidRoleListResponse(r, expected_length=0) + self.assertIn(collection_url, r.result['links']['self']) + + def test_crud_inherited_role_grants_failed_if_disabled(self): + # Disable the extension and check no API calls can be issued + self.opt_in_group('os_inherit', enabled=False) + super(IdentityIneritanceTestCase, self).setUp() + + role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.assignment_api.create_role(role['id'], role) + + base_collection_url = ( + '/OS-INHERIT/domains/%(domain_id)s/users/%(user_id)s/roles' % { + 'domain_id': self.domain_id, + 'user_id': self.user['id']}) + member_url = '%(collection_url)s/%(role_id)s/inherited_to_projects' % { + 'collection_url': base_collection_url, + 'role_id': role['id']} + collection_url = base_collection_url + '/inherited_to_projects' + + self.put(member_url, expected_status=404) + self.head(member_url, expected_status=404) + self.get(collection_url, expected_status=404) + self.delete(member_url, expected_status=404) + + def test_list_role_assignments_for_inherited_domain_grants(self): + """Call ``GET /role_assignments with inherited domain grants``. + + Test Plan: + - Create 4 roles + - Create a domain with a user and two projects + - Assign two direct roles to project1 + - Assign a spoiler role to project2 + - Issue the URL to add inherited role to the domain + - Issue the URL to check it is indeed on the domain + - Issue the URL to check effective roles on project1 - this + should return 3 roles. + + """ + role_list = [] + for _ in range(4): + role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.assignment_api.create_role(role['id'], role) + role_list.append(role) + + domain = self.new_domain_ref() + self.identity_api.create_domain(domain['id'], domain) + user1 = self.new_user_ref( + domain_id=domain['id']) + user1['password'] = uuid.uuid4().hex + self.identity_api.create_user(user1['id'], user1) + project1 = self.new_project_ref( + domain_id=domain['id']) + self.assignment_api.create_project(project1['id'], project1) + project2 = self.new_project_ref( + domain_id=domain['id']) + self.assignment_api.create_project(project2['id'], project2) + # Add some roles to the project + self.assignment_api.add_role_to_user_and_project( + user1['id'], project1['id'], role_list[0]['id']) + self.assignment_api.add_role_to_user_and_project( + user1['id'], project1['id'], role_list[1]['id']) + # ..and one on a different project as a spoiler + self.assignment_api.add_role_to_user_and_project( + user1['id'], project2['id'], role_list[2]['id']) + + # Now create our inherited role on the domain + base_collection_url = ( + '/OS-INHERIT/domains/%(domain_id)s/users/%(user_id)s/roles' % { + 'domain_id': domain['id'], + 'user_id': user1['id']}) + member_url = '%(collection_url)s/%(role_id)s/inherited_to_projects' % { + 'collection_url': base_collection_url, + 'role_id': role_list[3]['id']} + collection_url = base_collection_url + '/inherited_to_projects' + + self.put(member_url) + self.head(member_url) + r = self.get(collection_url) + self.assertValidRoleListResponse(r, ref=role_list[3]) + self.assertIn(collection_url, r.result['links']['self']) + + # Now use the list domain role assignments api to check if this + # is included + collection_url = ( + '/role_assignments?user.id=%(user_id)s' + '&scope.domain.id=%(domain_id)s' % { + 'user_id': user1['id'], + 'domain_id': domain['id']}) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), 1) + ud_url, ud_entity = _build_role_assignment_url_and_entity( + domain_id=domain['id'], user_id=user1['id'], + role_id=role_list[3]['id'], inherited_to_projects=True) + self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=ud_url) + + # Now ask for effective list role assignments - the role should + # turn into a project role, along with the two direct roles that are + # on the project + collection_url = ( + '/role_assignments?effective&user.id=%(user_id)s' + '&scope.project.id=%(project_id)s' % { + 'user_id': user1['id'], + 'project_id': project1['id']}) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), 3) + # An effective role for an inherited role will be a project + # entity, with a domain link to the inherited assignment + unused, up_entity = _build_role_assignment_url_and_entity( + project_id=project1['id'], user_id=user1['id'], + role_id=role_list[3]['id']) + ud_url, unused = _build_role_assignment_url_and_entity( + domain_id=domain['id'], user_id=user1['id'], + role_id=role_list[3]['id'], inherited_to_projects=True) + self.assertRoleAssignmentInListResponse(r, up_entity, link_url=ud_url) + + def test_list_role_assignments_for_disabled_inheritance_extension(self): + """Call ``GET /role_assignments with inherited domain grants``. + + Test Plan: + - Issue the URL to add inherited role to the domain + - Issue the URL to check effective roles on project include the + inherited role + - Disable the extension + - Re-check the effective roles, proving the inherited role no longer + shows up. + + """ + + role_list = [] + for _ in range(4): + role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.assignment_api.create_role(role['id'], role) + role_list.append(role) + + domain = self.new_domain_ref() + self.identity_api.create_domain(domain['id'], domain) + user1 = self.new_user_ref( + domain_id=domain['id']) + user1['password'] = uuid.uuid4().hex + self.identity_api.create_user(user1['id'], user1) + project1 = self.new_project_ref( + domain_id=domain['id']) + self.assignment_api.create_project(project1['id'], project1) + project2 = self.new_project_ref( + domain_id=domain['id']) + self.assignment_api.create_project(project2['id'], project2) + # Add some roles to the project + self.assignment_api.add_role_to_user_and_project( + user1['id'], project1['id'], role_list[0]['id']) + self.assignment_api.add_role_to_user_and_project( + user1['id'], project1['id'], role_list[1]['id']) + # ..and one on a different project as a spoiler + self.assignment_api.add_role_to_user_and_project( + user1['id'], project2['id'], role_list[2]['id']) + + # Now create our inherited role on the domain + base_collection_url = ( + '/OS-INHERIT/domains/%(domain_id)s/users/%(user_id)s/roles' % { + 'domain_id': domain['id'], + 'user_id': user1['id']}) + member_url = '%(collection_url)s/%(role_id)s/inherited_to_projects' % { + 'collection_url': base_collection_url, + 'role_id': role_list[3]['id']} + collection_url = base_collection_url + '/inherited_to_projects' + + self.put(member_url) + self.head(member_url) + r = self.get(collection_url) + self.assertValidRoleListResponse(r, ref=role_list[3]) + self.assertIn(collection_url, r.result['links']['self']) + + # Get effective list role assignments - the role should + # turn into a project role, along with the two direct roles that are + # on the project + collection_url = ( + '/role_assignments?effective&user.id=%(user_id)s' + '&scope.project.id=%(project_id)s' % { + 'user_id': user1['id'], + 'project_id': project1['id']}) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), 3) + + unused, up_entity = _build_role_assignment_url_and_entity( + project_id=project1['id'], user_id=user1['id'], + role_id=role_list[3]['id']) + ud_url, unused = _build_role_assignment_url_and_entity( + domain_id=domain['id'], user_id=user1['id'], + role_id=role_list[3]['id'], inherited_to_projects=True) + self.assertRoleAssignmentInListResponse(r, up_entity, link_url=ud_url) + + # Disable the extension and re-check the list, the role inherited + # from the project should no longer show up + self.opt_in_group('os_inherit', enabled=False) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), 2) + + unused, up_entity = _build_role_assignment_url_and_entity( + project_id=project1['id'], user_id=user1['id'], + role_id=role_list[3]['id']) + ud_url, unused = _build_role_assignment_url_and_entity( + domain_id=domain['id'], user_id=user1['id'], + role_id=role_list[3]['id'], inherited_to_projects=True) + self.assertRoleAssignmentNotInListResponse(r, up_entity, + link_url=ud_url) + + def test_list_role_assignments_for_inherited_group_domain_grants(self): + """Call ``GET /role_assignments with inherited group domain grants``. + + Test Plan: + - Create 4 roles + - Create a domain with a user and two projects + - Assign two direct roles to project1 + - Assign a spoiler role to project2 + - Issue the URL to add inherited role to the domain + - Issue the URL to check it is indeed on the domain + - Issue the URL to check effective roles on project1 - this + should return 3 roles. + + """ + role_list = [] + for _ in range(4): + role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.assignment_api.create_role(role['id'], role) + role_list.append(role) + + domain = self.new_domain_ref() + self.identity_api.create_domain(domain['id'], domain) + user1 = self.new_user_ref( + domain_id=domain['id']) + user1['password'] = uuid.uuid4().hex + self.identity_api.create_user(user1['id'], user1) + user2 = self.new_user_ref( + domain_id=domain['id']) + user2['password'] = uuid.uuid4().hex + self.identity_api.create_user(user2['id'], user2) + group1 = self.new_group_ref( + domain_id=domain['id']) + self.identity_api.create_group(group1['id'], group1) + self.identity_api.add_user_to_group(user1['id'], + group1['id']) + self.identity_api.add_user_to_group(user2['id'], + group1['id']) + project1 = self.new_project_ref( + domain_id=domain['id']) + self.assignment_api.create_project(project1['id'], project1) + project2 = self.new_project_ref( + domain_id=domain['id']) + self.assignment_api.create_project(project2['id'], project2) + # Add some roles to the project + self.assignment_api.add_role_to_user_and_project( + user1['id'], project1['id'], role_list[0]['id']) + self.assignment_api.add_role_to_user_and_project( + user1['id'], project1['id'], role_list[1]['id']) + # ..and one on a different project as a spoiler + self.assignment_api.add_role_to_user_and_project( + user1['id'], project2['id'], role_list[2]['id']) + + # Now create our inherited role on the domain + base_collection_url = ( + '/OS-INHERIT/domains/%(domain_id)s/groups/%(group_id)s/roles' % { + 'domain_id': domain['id'], + 'group_id': group1['id']}) + member_url = '%(collection_url)s/%(role_id)s/inherited_to_projects' % { + 'collection_url': base_collection_url, + 'role_id': role_list[3]['id']} + collection_url = base_collection_url + '/inherited_to_projects' + + self.put(member_url) + self.head(member_url) + r = self.get(collection_url) + self.assertValidRoleListResponse(r, ref=role_list[3]) + self.assertIn(collection_url, r.result['links']['self']) + + # Now use the list domain role assignments api to check if this + # is included + collection_url = ( + '/role_assignments?group.id=%(group_id)s' + '&scope.domain.id=%(domain_id)s' % { + 'group_id': group1['id'], + 'domain_id': domain['id']}) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), 1) + gd_url, gd_entity = _build_role_assignment_url_and_entity( + domain_id=domain['id'], group_id=group1['id'], + role_id=role_list[3]['id'], inherited_to_projects=True) + self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) + + # Now ask for effective list role assignments - the role should + # turn into a user project role, along with the two direct roles + # that are on the project + collection_url = ( + '/role_assignments?effective&user.id=%(user_id)s' + '&scope.project.id=%(project_id)s' % { + 'user_id': user1['id'], + 'project_id': project1['id']}) + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), 3) + # An effective role for an inherited role will be a project + # entity, with a domain link to the inherited assignment + unused, up_entity = _build_role_assignment_url_and_entity( + project_id=project1['id'], user_id=user1['id'], + role_id=role_list[3]['id']) + gd_url, unused = _build_role_assignment_url_and_entity( + domain_id=domain['id'], group_id=group1['id'], + role_id=role_list[3]['id'], inherited_to_projects=True) + self.assertRoleAssignmentInListResponse(r, up_entity, link_url=gd_url) + + def test_filtered_role_assignments_for_inherited_grants(self): + """Call ``GET /role_assignments?scope.OS-INHERIT:inherited_to``. + + Test Plan: + - Create 5 roles + - Create a domain with a user, group and two projects + - Assign three direct spoiler roles to projects + - Issue the URL to add an inherited user role to the domain + - Issue the URL to add an inherited group role to the domain + - Issue the URL to filter by inherited roles - this should + return just the 2 inherited roles. + + """ + role_list = [] + for _ in range(5): + role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.assignment_api.create_role(role['id'], role) + role_list.append(role) + + domain = self.new_domain_ref() + self.identity_api.create_domain(domain['id'], domain) + user1 = self.new_user_ref( + domain_id=domain['id']) + user1['password'] = uuid.uuid4().hex + self.identity_api.create_user(user1['id'], user1) + group1 = self.new_group_ref( + domain_id=domain['id']) + self.identity_api.create_group(group1['id'], group1) + project1 = self.new_project_ref( + domain_id=domain['id']) + self.assignment_api.create_project(project1['id'], project1) + project2 = self.new_project_ref( + domain_id=domain['id']) + self.assignment_api.create_project(project2['id'], project2) + # Add some spoiler roles to the projects + self.assignment_api.add_role_to_user_and_project( + user1['id'], project1['id'], role_list[0]['id']) + self.assignment_api.add_role_to_user_and_project( + user1['id'], project2['id'], role_list[1]['id']) + # Create a non-inherited role as a spoiler + self.assignment_api.create_grant( + role_list[2]['id'], user_id=user1['id'], domain_id=domain['id']) + + # Now create two inherited roles on the domain, one for a user + # and one for a domain + base_collection_url = ( + '/OS-INHERIT/domains/%(domain_id)s/users/%(user_id)s/roles' % { + 'domain_id': domain['id'], + 'user_id': user1['id']}) + member_url = '%(collection_url)s/%(role_id)s/inherited_to_projects' % { + 'collection_url': base_collection_url, + 'role_id': role_list[3]['id']} + collection_url = base_collection_url + '/inherited_to_projects' + + self.put(member_url) + self.head(member_url) + r = self.get(collection_url) + self.assertValidRoleListResponse(r, ref=role_list[3]) + self.assertIn(collection_url, r.result['links']['self']) + + base_collection_url = ( + '/OS-INHERIT/domains/%(domain_id)s/groups/%(group_id)s/roles' % { + 'domain_id': domain['id'], + 'group_id': group1['id']}) + member_url = '%(collection_url)s/%(role_id)s/inherited_to_projects' % { + 'collection_url': base_collection_url, + 'role_id': role_list[4]['id']} + collection_url = base_collection_url + '/inherited_to_projects' + + self.put(member_url) + self.head(member_url) + r = self.get(collection_url) + self.assertValidRoleListResponse(r, ref=role_list[4]) + self.assertIn(collection_url, r.result['links']['self']) + + # Now use the list role assignments api to get a list of inherited + # roles on the domain - should get back the two roles + collection_url = ( + '/role_assignments?scope.OS-INHERIT:inherited_to=projects') + r = self.get(collection_url) + self.assertValidRoleAssignmentListResponse(r) + self.assertEqual(len(r.result.get('role_assignments')), 2) + ud_url, ud_entity = _build_role_assignment_url_and_entity( + domain_id=domain['id'], user_id=user1['id'], + role_id=role_list[3]['id'], inherited_to_projects=True) + gd_url, gd_entity = _build_role_assignment_url_and_entity( + domain_id=domain['id'], group_id=group1['id'], + role_id=role_list[4]['id'], inherited_to_projects=True) + self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=ud_url) + self.assertRoleAssignmentInListResponse(r, gd_entity, link_url=gd_url) diff --git a/tests/test_versions.py b/tests/test_versions.py index 58ace878..c5864c37 100644 --- a/tests/test_versions.py +++ b/tests/test_versions.py @@ -176,7 +176,6 @@ class VersionTestCase(test.TestCase): self.assertEqual(data, expected) def test_public_version_v3(self): - print CONF.public_port client = self.client(self.public_app) resp = client.get('/v3/') self.assertEqual(resp.status_int, 200) diff --git a/tests/test_wsgi.py b/tests/test_wsgi.py index c73212c8..003f7571 100644 --- a/tests/test_wsgi.py +++ b/tests/test_wsgi.py @@ -14,8 +14,6 @@ # License for the specific language governing permissions and limitations # under the License. -import webob - from keystone import test from keystone.common import wsgi @@ -34,7 +32,7 @@ class BaseWSGITest(test.TestCase): super(BaseWSGITest, self).setUp() def _make_request(self, url='/'): - req = webob.Request.blank(url) + req = wsgi.Request.blank(url) args = {'action': 'index', 'controller': None} req.environ['wsgiorg.routing_args'] = [None, args] return req @@ -125,6 +123,32 @@ class ApplicationTest(BaseWSGITest): self.assertEqual(resp.headers.get('Content-Length'), '0') self.assertEqual(resp.headers.get('Content-Type'), None) + def test_application_local_config(self): + class FakeApp(wsgi.Application): + def __init__(self, *args, **kwargs): + self.kwargs = kwargs + + app = FakeApp.factory({}, testkey="test") + self.assertIn("testkey", app.kwargs) + self.assertEquals("test", app.kwargs["testkey"]) + + def test_render_exception(self): + e = exception.Unauthorized(message=u'\u7f51\u7edc') + resp = wsgi.render_exception(e) + self.assertEqual(resp.status_int, 401) + + +class ExtensionRouterTest(BaseWSGITest): + def test_extensionrouter_local_config(self): + class FakeRouter(wsgi.ExtensionRouter): + def __init__(self, *args, **kwargs): + self.kwargs = kwargs + + factory = FakeRouter.factory({}, testkey="test") + app = factory(self.app) + self.assertIn("testkey", app.kwargs) + self.assertEquals("test", app.kwargs["testkey"]) + class MiddlewareTest(BaseWSGITest): def test_middleware_request(self): diff --git a/tests/tmp/.gitkeep b/tests/tmp/.gitkeep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/tests/tmp/.gitkeep diff --git a/tools/install_venv_common.py b/tools/install_venv_common.py index 42a44e8c..f428c1e0 100644 --- a/tools/install_venv_common.py +++ b/tools/install_venv_common.py @@ -34,12 +34,13 @@ import sys class InstallVenv(object): - def __init__(self, root, venv, pip_requires, test_requires, py_version, + def __init__(self, root, venv, requirements, + test_requirements, py_version, project): self.root = root self.venv = venv - self.pip_requires = pip_requires - self.test_requires = test_requires + self.requirements = requirements + self.test_requirements = test_requirements self.py_version = py_version self.project = project @@ -75,11 +76,13 @@ class InstallVenv(object): def get_distro(self): if (os.path.exists('/etc/fedora-release') or os.path.exists('/etc/redhat-release')): - return Fedora(self.root, self.venv, self.pip_requires, - self.test_requires, self.py_version, self.project) + return Fedora( + self.root, self.venv, self.requirements, + self.test_requirements, self.py_version, self.project) else: - return Distro(self.root, self.venv, self.pip_requires, - self.test_requires, self.py_version, self.project) + return Distro( + self.root, self.venv, self.requirements, + self.test_requirements, self.py_version, self.project) def check_dependencies(self): self.get_distro().install_virtualenv() @@ -98,11 +101,6 @@ class InstallVenv(object): else: self.run_command(['virtualenv', '-q', self.venv]) print('done.') - print('Installing pip in venv...', end=' ') - if not self.run_command(['tools/with_venv.sh', 'easy_install', - 'pip>1.0']).strip(): - self.die("Failed to install pip.") - print('done.') else: print("venv already exists...") pass @@ -116,20 +114,12 @@ class InstallVenv(object): print('Installing dependencies with pip (this can take a while)...') # First things first, make sure our venv has the latest pip and - # distribute. - # NOTE: we keep pip at version 1.1 since the most recent version causes - # the .venv creation to fail. See: - # https://bugs.launchpad.net/nova/+bug/1047120 - self.pip_install('pip==1.1') - self.pip_install('distribute') - - # Install greenlet by hand - just listing it in the requires file does - # not - # get it installed in the right order - self.pip_install('greenlet') - - self.pip_install('-r', self.pip_requires) - self.pip_install('-r', self.test_requires) + # setuptools. + self.pip_install('pip>=1.3') + self.pip_install('setuptools') + + self.pip_install('-r', self.requirements) + self.pip_install('-r', self.test_requirements) def post_process(self): self.get_distro().post_process() @@ -1,5 +1,5 @@ [tox] -envlist = py26,py27,pep8 +envlist = py26,py27,py33,pep8 [testenv] setenv = VIRTUAL_ENV={envdir} |