Update keystone to the branch stable/liberty. 73/3873/1
authorasteroide <thomas.duval@orange.com>
Wed, 2 Dec 2015 08:49:33 +0000 (09:49 +0100)
committerasteroide <thomas.duval@orange.com>
Wed, 2 Dec 2015 09:25:15 +0000 (10:25 +0100)
Change-Id: I7cce62ae4b4cbca525a7b9499285455bdd04993e

91 files changed:
keystone-moon/doc/source/configuration.rst
keystone-moon/etc/keystone.conf.sample
keystone-moon/keystone/assignment/controllers.py
keystone-moon/keystone/catalog/controllers.py
keystone-moon/keystone/common/config.py
keystone-moon/keystone/common/ldap/core.py
keystone-moon/keystone/contrib/federation/migrate_repo/versions/007_add_remote_id_table.py
keystone-moon/keystone/identity/controllers.py
keystone-moon/keystone/locale/de/LC_MESSAGES/keystone-log-critical.po
keystone-moon/keystone/locale/de/LC_MESSAGES/keystone.po
keystone-moon/keystone/locale/el/LC_MESSAGES/keystone-log-critical.po
keystone-moon/keystone/locale/en_AU/LC_MESSAGES/keystone-log-critical.po
keystone-moon/keystone/locale/en_AU/LC_MESSAGES/keystone-log-error.po
keystone-moon/keystone/locale/en_AU/LC_MESSAGES/keystone.po
keystone-moon/keystone/locale/es/LC_MESSAGES/keystone-log-critical.po
keystone-moon/keystone/locale/es/LC_MESSAGES/keystone.po
keystone-moon/keystone/locale/fr/LC_MESSAGES/keystone-log-critical.po
keystone-moon/keystone/locale/fr/LC_MESSAGES/keystone-log-error.po
keystone-moon/keystone/locale/fr/LC_MESSAGES/keystone-log-info.po
keystone-moon/keystone/locale/fr/LC_MESSAGES/keystone-log-warning.po
keystone-moon/keystone/locale/fr/LC_MESSAGES/keystone.po
keystone-moon/keystone/locale/hu/LC_MESSAGES/keystone-log-critical.po
keystone-moon/keystone/locale/it/LC_MESSAGES/keystone-log-critical.po
keystone-moon/keystone/locale/it/LC_MESSAGES/keystone.po
keystone-moon/keystone/locale/ja/LC_MESSAGES/keystone-log-critical.po
keystone-moon/keystone/locale/ja/LC_MESSAGES/keystone.po
keystone-moon/keystone/locale/keystone-log-warning.pot
keystone-moon/keystone/locale/keystone.pot
keystone-moon/keystone/locale/ko_KR/LC_MESSAGES/keystone-log-critical.po
keystone-moon/keystone/locale/ko_KR/LC_MESSAGES/keystone.po
keystone-moon/keystone/locale/pl_PL/LC_MESSAGES/keystone-log-critical.po
keystone-moon/keystone/locale/pt_BR/LC_MESSAGES/keystone-log-critical.po
keystone-moon/keystone/locale/pt_BR/LC_MESSAGES/keystone-log-error.po
keystone-moon/keystone/locale/pt_BR/LC_MESSAGES/keystone.po
keystone-moon/keystone/locale/ru/LC_MESSAGES/keystone-log-critical.po
keystone-moon/keystone/locale/ru/LC_MESSAGES/keystone.po
keystone-moon/keystone/locale/tr_TR/LC_MESSAGES/keystone-log-critical.po
keystone-moon/keystone/locale/tr_TR/LC_MESSAGES/keystone-log-error.po
keystone-moon/keystone/locale/tr_TR/LC_MESSAGES/keystone-log-info.po
keystone-moon/keystone/locale/tr_TR/LC_MESSAGES/keystone-log-warning.po
keystone-moon/keystone/locale/tr_TR/LC_MESSAGES/keystone.po
keystone-moon/keystone/locale/zh_CN/LC_MESSAGES/keystone-log-critical.po
keystone-moon/keystone/locale/zh_CN/LC_MESSAGES/keystone-log-error.po
keystone-moon/keystone/locale/zh_CN/LC_MESSAGES/keystone-log-info.po
keystone-moon/keystone/locale/zh_CN/LC_MESSAGES/keystone.po
keystone-moon/keystone/locale/zh_TW/LC_MESSAGES/keystone-log-critical.po
keystone-moon/keystone/locale/zh_TW/LC_MESSAGES/keystone.po
keystone-moon/keystone/resource/controllers.py
keystone-moon/keystone/resource/core.py
keystone-moon/keystone/tests/unit/common/test_notifications.py
keystone-moon/keystone/tests/unit/rest.py
keystone-moon/keystone/tests/unit/test_associate_project_endpoint_extension.py
keystone-moon/keystone/tests/unit/test_backend.py
keystone-moon/keystone/tests/unit/test_backend_ldap.py
keystone-moon/keystone/tests/unit/test_catalog.py
keystone-moon/keystone/tests/unit/test_cert_setup.py
keystone-moon/keystone/tests/unit/test_contrib_simple_cert.py
keystone-moon/keystone/tests/unit/test_policy.py
keystone-moon/keystone/tests/unit/test_sql_migrate_extensions.py
keystone-moon/keystone/tests/unit/test_v2.py
keystone-moon/keystone/tests/unit/test_v2_keystoneclient.py
keystone-moon/keystone/tests/unit/test_v3.py
keystone-moon/keystone/tests/unit/test_v3_assignment.py
keystone-moon/keystone/tests/unit/test_v3_auth.py
keystone-moon/keystone/tests/unit/test_v3_catalog.py
keystone-moon/keystone/tests/unit/test_v3_credential.py
keystone-moon/keystone/tests/unit/test_v3_domain_config.py
keystone-moon/keystone/tests/unit/test_v3_endpoint_policy.py
keystone-moon/keystone/tests/unit/test_v3_federation.py
keystone-moon/keystone/tests/unit/test_v3_identity.py
keystone-moon/keystone/tests/unit/test_v3_oauth1.py
keystone-moon/keystone/tests/unit/test_v3_protection.py
keystone-moon/keystone/tests/unit/test_versions.py
keystone-moon/keystone/tests/unit/test_wsgi.py
keystone-moon/keystone/tests/unit/token/test_fernet_provider.py
keystone-moon/keystone/token/providers/fernet/core.py
keystone-moon/keystone/token/providers/fernet/token_formatters.py
keystone-moon/releasenotes/notes/.placeholder [new file with mode: 0644]
keystone-moon/releasenotes/notes/deprecations-c4afc19dc5324b9c.yaml [new file with mode: 0644]
keystone-moon/releasenotes/notes/new_features-e33d793d8a5ca76a.yaml [new file with mode: 0644]
keystone-moon/releasenotes/notes/upgrade_notes-ca81f5d531ab3522.yaml [new file with mode: 0644]
keystone-moon/releasenotes/source/_static/.placeholder [new file with mode: 0644]
keystone-moon/releasenotes/source/_templates/.placeholder [new file with mode: 0644]
keystone-moon/releasenotes/source/conf.py [new file with mode: 0644]
keystone-moon/releasenotes/source/index.rst [new file with mode: 0644]
keystone-moon/releasenotes/source/liberty.rst [new file with mode: 0644]
keystone-moon/releasenotes/source/unreleased.rst [new file with mode: 0644]
keystone-moon/requirements.txt
keystone-moon/setup.cfg
keystone-moon/test-requirements.txt
keystone-moon/tox.ini

index 9649166..574b26b 100644 (file)
@@ -1637,9 +1637,9 @@ have been created. They are enabled by setting their respective flags to True.
 Then the attributes ``user_enabled_emulation_dn`` and
 ``project_enabled_emulation_dn`` may be set to specify how the enabled users
 and projects (tenants) are selected. These attributes work by using a
-``groupOfNames`` and adding whichever users or projects (tenants) that you want
-enabled to the respective group. For example, this will mark any user who is a
-member of ``enabled_users`` as enabled:
+``groupOfNames`` entry and adding whichever users or projects (tenants) that
+you want enabled to the respective group with the ``member`` attribute. For
+example, this will mark any user who is a member of ``enabled_users`` as enabled:
 
 .. code-block:: ini
 
@@ -1651,6 +1651,12 @@ The default values for user and project (tenant) enabled emulation DN is
 ``cn=enabled_users,$user_tree_dn`` and ``cn=enabled_tenants,$project_tree_dn``
 respectively.
 
+If a different LDAP schema is used for group membership, it is possible to use
+the ``group_objectclass`` and ``group_member_attribute`` attributes to
+determine membership in the enabled emulation group by setting the
+``user_enabled_emulation_use_group_config`` and
+``project_enabled_emulation_use_group_config`` attributes to True.
+
 Secure Connection
 -----------------
 
index 9c76fc0..8e5ea13 100644 (file)
 # A list of trusted dashboard hosts. Before accepting a Single Sign-On request
 # to return a token, the origin host must be a member of the trusted_dashboard
 # list. This configuration option may be repeated for multiple values. For
-# example: trusted_dashboard=http://acme.com/auth/websso
-# trusted_dashboard=http://beta.com/auth/websso (multi valued)
+# example: trusted_dashboard=http://acme.com trusted_dashboard=http://beta.com
+# (multi valued)
 #trusted_dashboard =
 
 # Location of Single Sign-On callback handler, will return a token to a trusted
 # (string value)
 #user_enabled_emulation_dn = <None>
 
+# Use the "group_member_attribute" and "group_objectclass" settings to
+# determine membership in the emulated enabled group. (boolean value)
+#user_enabled_emulation_use_group_config = false
+
 # List of additional LDAP attributes used for mapping additional attribute
 # mappings for users. Attribute mapping format is <ldap_attr>:<user_attr>,
 # where ldap_attr is the attribute in the LDAP entry and user_attr is the
 # Its value may be silently ignored in the future.
 #project_enabled_emulation_dn = <None>
 
+# Use the "group_member_attribute" and "group_objectclass" settings to
+# determine membership in the emulated enabled group. (boolean value)
+#project_enabled_emulation_use_group_config = false
+
 # Additional attribute mappings for projects. Attribute mapping format is
 # <ldap_attr>:<user_attr>, where ldap_attr is the attribute in the LDAP entry
 # and user_attr is the Identity API attribute. (list value)
index d33dce7..bbaf943 100644 (file)
@@ -108,13 +108,15 @@ class Role(controller.V2Controller):
             role_id = uuid.uuid4().hex
 
         role['id'] = role_id
-        role_ref = self.role_api.create_role(role_id, role)
+        initiator = notifications._get_request_audit_info(context)
+        role_ref = self.role_api.create_role(role_id, role, initiator)
         return {'role': role_ref}
 
     @controller.v2_deprecated
     def delete_role(self, context, role_id):
         self.assert_admin(context)
-        self.role_api.delete_role(role_id)
+        initiator = notifications._get_request_audit_info(context)
+        self.role_api.delete_role(role_id, initiator)
 
     @controller.v2_deprecated
     def get_roles(self, context):
index 92046e8..e14b268 100644 (file)
@@ -47,7 +47,8 @@ class Service(controller.V2Controller):
     @controller.v2_deprecated
     def delete_service(self, context, service_id):
         self.assert_admin(context)
-        self.catalog_api.delete_service(service_id)
+        initiator = notifications._get_request_audit_info(context)
+        self.catalog_api.delete_service(service_id, initiator)
 
     @controller.v2_deprecated
     def create_service(self, context, OS_KSADM_service):
@@ -55,8 +56,9 @@ class Service(controller.V2Controller):
         service_id = uuid.uuid4().hex
         service_ref = OS_KSADM_service.copy()
         service_ref['id'] = service_id
+        initiator = notifications._get_request_audit_info(context)
         new_service_ref = self.catalog_api.create_service(
-            service_id, service_ref)
+            service_id, service_ref, initiator)
         return {'OS-KSADM:service': new_service_ref}
 
 
@@ -68,25 +70,59 @@ class Endpoint(controller.V2Controller):
         """Merge matching v3 endpoint refs into legacy refs."""
         self.assert_admin(context)
         legacy_endpoints = {}
+        v3_endpoints = {}
         for endpoint in self.catalog_api.list_endpoints():
-            if not endpoint.get('legacy_endpoint_id'):
-                # endpoints created in v3 should not appear on the v2 API
+            if not endpoint.get('legacy_endpoint_id'):  # pure v3 endpoint
+                # tell endpoints apart by the combination of
+                # service_id and region_id.
+                # NOTE(muyu): in theory, it's possible that there are more than
+                # one endpoint of one service, one region and one interface,
+                # but in practice, it makes no sense because only one will be
+                # used.
+                key = (endpoint['service_id'], endpoint['region_id'])
+                v3_endpoints.setdefault(key, []).append(endpoint)
+            else:  # legacy endpoint
+                if endpoint['legacy_endpoint_id'] not in legacy_endpoints:
+                    legacy_ep = endpoint.copy()
+                    legacy_ep['id'] = legacy_ep.pop('legacy_endpoint_id')
+                    legacy_ep.pop('interface')
+                    legacy_ep.pop('url')
+                    legacy_ep['region'] = legacy_ep.pop('region_id')
+
+                    legacy_endpoints[endpoint['legacy_endpoint_id']] = (
+                        legacy_ep)
+                else:
+                    legacy_ep = (
+                        legacy_endpoints[endpoint['legacy_endpoint_id']])
+
+                # add the legacy endpoint with an interface url
+                legacy_ep['%surl' % endpoint['interface']] = endpoint['url']
+
+        # convert collected v3 endpoints into v2 endpoints
+        for endpoints in v3_endpoints.values():
+            legacy_ep = {}
+            # For v3 endpoints in the same group, contents of extra attributes
+            # can be different, which may cause confusion if a random one is
+            # used. So only necessary attributes are used here.
+            # It's different for legacy v2 endpoints, which are created
+            # with the same "extra" value when being migrated.
+            for key in ('service_id', 'enabled'):
+                legacy_ep[key] = endpoints[0][key]
+            legacy_ep['region'] = endpoints[0]['region_id']
+            for endpoint in endpoints:
+                # Public URL is required for v2 endpoints, so the generated v2
+                # endpoint uses public endpoint's id as its id, which can also
+                # be an indicator whether a public v3 endpoint is present.
+                # It's safe to do so is also because that there is no v2 API to
+                # get an endpoint by endpoint ID.
+                if endpoint['interface'] == 'public':
+                    legacy_ep['id'] = endpoint['id']
+                legacy_ep['%surl' % endpoint['interface']] = endpoint['url']
+
+            # this means there is no public URL of this group of v3 endpoints
+            if 'id' not in legacy_ep:
                 continue
-
-            # is this is a legacy endpoint we haven't indexed yet?
-            if endpoint['legacy_endpoint_id'] not in legacy_endpoints:
-                legacy_ep = endpoint.copy()
-                legacy_ep['id'] = legacy_ep.pop('legacy_endpoint_id')
-                legacy_ep.pop('interface')
-                legacy_ep.pop('url')
-                legacy_ep['region'] = legacy_ep.pop('region_id')
-
-                legacy_endpoints[endpoint['legacy_endpoint_id']] = legacy_ep
-            else:
-                legacy_ep = legacy_endpoints[endpoint['legacy_endpoint_id']]
-
-            # add the legacy endpoint with an interface url
-            legacy_ep['%surl' % endpoint['interface']] = endpoint['url']
+            legacy_endpoints[legacy_ep['id']] = legacy_ep
         return {'endpoints': list(legacy_endpoints.values())}
 
     @controller.v2_deprecated
@@ -148,11 +184,12 @@ class Endpoint(controller.V2Controller):
     def delete_endpoint(self, context, endpoint_id):
         """Delete up to three v3 endpoint refs based on a legacy ref ID."""
         self.assert_admin(context)
+        initiator = notifications._get_request_audit_info(context)
 
         deleted_at_least_one = False
         for endpoint in self.catalog_api.list_endpoints():
             if endpoint['legacy_endpoint_id'] == endpoint_id:
-                self.catalog_api.delete_endpoint(endpoint['id'])
+                self.catalog_api.delete_endpoint(endpoint['id'], initiator)
                 deleted_at_least_one = True
 
         if not deleted_at_least_one:
index fcf05ab..4ba740f 100644 (file)
@@ -668,6 +668,10 @@ FILE_OPTIONS = {
         cfg.StrOpt('user_enabled_emulation_dn',
                    help='DN of the group entry to hold enabled users when '
                         'using enabled emulation.'),
+        cfg.BoolOpt('user_enabled_emulation_use_group_config', default=False,
+                    help='Use the "group_member_attribute" and '
+                         '"group_objectclass" settings to determine '
+                         'membership in the emulated enabled group.'),
         cfg.ListOpt('user_additional_attribute_mapping',
                     default=[],
                     help='List of additional LDAP attributes used for mapping '
@@ -759,6 +763,11 @@ FILE_OPTIONS = {
                    deprecated_for_removal=True,
                    help='DN of the group entry to hold enabled projects when '
                         'using enabled emulation.'),
+        cfg.BoolOpt('project_enabled_emulation_use_group_config',
+                    default=False,
+                    help='Use the "group_member_attribute" and '
+                         '"group_objectclass" settings to determine '
+                         'membership in the emulated enabled group.'),
         cfg.ListOpt('project_additional_attribute_mapping',
                     deprecated_opts=[cfg.DeprecatedOpt(
                         'tenant_additional_attribute_mapping', group='ldap')],
@@ -1191,6 +1200,7 @@ FILE_OPTIONS = {
                    default='policy_root',
                    help='Local directory where Root IntraExtension configuration is stored.'),
     ]
+
 }
 
 
index 0bb3830..6386ae2 100644 (file)
@@ -1771,19 +1771,23 @@ class BaseLdap(object):
 class EnabledEmuMixIn(BaseLdap):
     """Emulates boolean 'enabled' attribute if turned on.
 
-    Creates groupOfNames holding all enabled objects of this class, all missing
+    Creates a group holding all enabled objects of this class, all missing
     objects are considered disabled.
 
     Options:
 
     * $name_enabled_emulation - boolean, on/off
-    * $name_enabled_emulation_dn - DN of that groupOfNames, default is
+    * $name_enabled_emulation_dn - DN of that group, default is
       cn=enabled_${name}s,${tree_dn}
+    * $name_enabled_emulation_use_group_config - boolean, on/off
 
     Where ${name}s is the plural of self.options_name ('users' or 'tenants'),
     ${tree_dn} is self.tree_dn.
     """
 
+    DEFAULT_GROUP_OBJECTCLASS = 'groupOfNames'
+    DEFAULT_MEMBER_ATTRIBUTE = 'member'
+
     def __init__(self, conf):
         super(EnabledEmuMixIn, self).__init__(conf)
         enabled_emulation = '%s_enabled_emulation' % self.options_name
@@ -1791,6 +1795,18 @@ class EnabledEmuMixIn(BaseLdap):
 
         enabled_emulation_dn = '%s_enabled_emulation_dn' % self.options_name
         self.enabled_emulation_dn = getattr(conf.ldap, enabled_emulation_dn)
+
+        use_group_config = ('%s_enabled_emulation_use_group_config' %
+                            self.options_name)
+        self.use_group_config = getattr(conf.ldap, use_group_config)
+
+        if not self.use_group_config:
+            self.member_attribute = self.DEFAULT_MEMBER_ATTRIBUTE
+            self.group_objectclass = self.DEFAULT_GROUP_OBJECTCLASS
+        else:
+            self.member_attribute = conf.ldap.group_member_attribute
+            self.group_objectclass = conf.ldap.group_objectclass
+
         if not self.enabled_emulation_dn:
             naming_attr_name = 'cn'
             naming_attr_value = 'enabled_%ss' % self.options_name
@@ -1807,7 +1823,7 @@ class EnabledEmuMixIn(BaseLdap):
 
     def _get_enabled(self, object_id, conn):
         dn = self._id_to_dn(object_id)
-        query = '(member=%s)' % dn
+        query = '(%s=%s)' % (self.member_attribute, dn)
         try:
             enabled_value = conn.search_s(self.enabled_emulation_dn,
                                           ldap.SCOPE_BASE,
@@ -1821,13 +1837,14 @@ class EnabledEmuMixIn(BaseLdap):
         with self.get_connection() as conn:
             if not self._get_enabled(object_id, conn):
                 modlist = [(ldap.MOD_ADD,
-                            'member',
+                            self.member_attribute,
                             [self._id_to_dn(object_id)])]
                 try:
                     conn.modify_s(self.enabled_emulation_dn, modlist)
                 except ldap.NO_SUCH_OBJECT:
-                    attr_list = [('objectClass', ['groupOfNames']),
-                                 ('member', [self._id_to_dn(object_id)]),
+                    attr_list = [('objectClass', [self.group_objectclass]),
+                                 (self.member_attribute,
+                                  [self._id_to_dn(object_id)]),
                                  self.enabled_emulation_naming_attr]
                     if self.use_dumb_member:
                         attr_list[1][1].append(self.dumb_member)
@@ -1835,7 +1852,7 @@ class EnabledEmuMixIn(BaseLdap):
 
     def _remove_enabled(self, object_id):
         modlist = [(ldap.MOD_DELETE,
-                    'member',
+                    self.member_attribute,
                     [self._id_to_dn(object_id)])]
         with self.get_connection() as conn:
             try:
index cd57124..77012aa 100644 (file)
@@ -32,7 +32,9 @@ def upgrade(migrate_engine):
 
     remote_id_table.create(migrate_engine, checkfirst=True)
 
-    select = orm.sql.select([idp_table.c.id, idp_table.c.remote_id])
+    select = orm.sql.select([idp_table.c.id, idp_table.c.remote_id]).where(
+        idp_table.c.remote_id.isnot(None))
+
     for identity in migrate_engine.execute(select):
         remote_idp_entry = {'idp_id': identity.id,
                             'remote_id': identity.remote_id}
index 7a6a642..0ec3819 100644 (file)
@@ -82,8 +82,9 @@ class User(controller.V2Controller):
 
         # The manager layer will generate the unique ID for users
         user_ref = self._normalize_domain_id(context, user.copy())
+        initiator = notifications._get_request_audit_info(context)
         new_user_ref = self.v3_to_v2_user(
-            self.identity_api.create_user(user_ref))
+            self.identity_api.create_user(user_ref, initiator))
 
         if default_project_id is not None:
             self.assignment_api.add_user_to_project(default_project_id,
@@ -120,8 +121,9 @@ class User(controller.V2Controller):
             # user update.
             self.resource_api.get_project(default_project_id)
 
+        initiator = notifications._get_request_audit_info(context)
         user_ref = self.v3_to_v2_user(
-            self.identity_api.update_user(user_id, user))
+            self.identity_api.update_user(user_id, user, initiator))
 
         # If 'tenantId' is in either ref, we might need to add or remove the
         # user from a project.
@@ -166,7 +168,8 @@ class User(controller.V2Controller):
     @controller.v2_deprecated
     def delete_user(self, context, user_id):
         self.assert_admin(context)
-        self.identity_api.delete_user(user_id)
+        initiator = notifications._get_request_audit_info(context)
+        self.identity_api.delete_user(user_id, initiator)
 
     @controller.v2_deprecated
     def set_user_enabled(self, context, user_id, user):
index 0403952..a9cfc70 100644 (file)
@@ -3,21 +3,22 @@
 # This file is distributed under the same license as the keystone project.
 #
 # Translators:
+# OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: Keystone\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-08-06 06:28+0000\n"
-"PO-Revision-Date: 2014-08-31 15:19+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
+"PO-Revision-Date: 2014-08-31 03:19+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: German (http://www.transifex.com/openstack/keystone/language/"
-"de/)\n"
+"Language-Team: German\n"
 "Language: de\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Generated-By: Babel 2.0\n"
+"X-Generator: Zanata 3.7.1\n"
 
 #, python-format
 msgid "Unable to open template file %s"
index 1b2f109..6f86075 100644 (file)
 # Tom Cocozzello <tjcocozz@us.ibm.com>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 9.0.0.dev14\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-24 06:09+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-09-03 12:54+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: German (http://www.transifex.com/openstack/keystone/language/"
-"de/)\n"
+"Language: de\n"
+"Language-Team: German\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 2.0\n"
+"Generated-By: Babel 2.1.1\n"
 
 #, python-format
 msgid "%(detail)s"
index 1dffb34..90f983b 100644 (file)
@@ -4,21 +4,22 @@
 #
 # Translators:
 # Efstathios Iosifidis <iefstathios@gmail.com>, 2015
+# OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: Keystone\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-08 06:08+0000\n"
-"PO-Revision-Date: 2015-09-05 13:09+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
+"PO-Revision-Date: 2015-09-05 01:09+0000\n"
 "Last-Translator: Efstathios Iosifidis <iefstathios@gmail.com>\n"
-"Language-Team: Greek (http://www.transifex.com/openstack/keystone/language/"
-"el/)\n"
+"Language-Team: Greek\n"
 "Language: el\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Generated-By: Babel 2.0\n"
+"X-Generator: Zanata 3.7.1\n"
 
 #, python-format
 msgid "Unable to open template file %s"
index 9959095..5576d06 100644 (file)
@@ -6,19 +6,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 8.0.0.0b4.dev56\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-21 06:08+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2014-08-31 03:19+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: English (Australia) (http://www.transifex.com/openstack/"
-"keystone/language/en_AU/)\n"
+"Language-Team: English (Australia)\n"
 "Language: en-AU\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Generated-By: Babel 2.0\n"
 "X-Generator: Zanata 3.7.1\n"
 
 #, python-format
index 7fd91ea..141e7ec 100644 (file)
@@ -6,19 +6,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 8.0.0.0b4.dev56\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-21 06:08+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-06-26 05:13+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: English (Australia) (http://www.transifex.com/openstack/"
-"keystone/language/en_AU/)\n"
+"Language-Team: English (Australia)\n"
 "Language: en-AU\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Generated-By: Babel 2.0\n"
 "X-Generator: Zanata 3.7.1\n"
 
 msgid ""
index dca5aa9..f290a11 100644 (file)
@@ -4,20 +4,21 @@
 #
 # Translators:
 # Tom Fifield <tom@openstack.org>, 2013
+# OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version:  Keystone\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-08-06 06:28+0000\n"
-"PO-Revision-Date: 2015-08-04 18:01+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
+"PO-Revision-Date: 2015-09-03 12:54+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: English (Australia) (http://www.transifex.com/openstack/"
-"keystone/language/en_AU/)\n"
+"Language: en_AU\n"
+"Language-Team: English (Australia)\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 2.0\n"
+"Generated-By: Babel 2.1.1\n"
 
 #, python-format
 msgid "%(property_name)s cannot be less than %(min_length)s characters."
index 336c5d3..9b93b5e 100644 (file)
@@ -3,21 +3,22 @@
 # This file is distributed under the same license as the keystone project.
 #
 # Translators:
+# OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: Keystone\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-08-06 06:28+0000\n"
-"PO-Revision-Date: 2014-08-31 15:19+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
+"PO-Revision-Date: 2014-08-31 03:19+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Spanish (http://www.transifex.com/openstack/keystone/language/"
-"es/)\n"
+"Language-Team: Spanish\n"
 "Language: es\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Generated-By: Babel 2.0\n"
+"X-Generator: Zanata 3.7.1\n"
 
 #, python-format
 msgid "Unable to open template file %s"
index 7075235..46520ca 100644 (file)
 # Tom Cocozzello <tjcocozz@us.ibm.com>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 9.0.0.dev14\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-24 06:09+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-09-03 12:54+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Spanish (http://www.transifex.com/openstack/keystone/language/"
-"es/)\n"
+"Language: es\n"
+"Language-Team: Spanish\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 2.0\n"
+"Generated-By: Babel 2.1.1\n"
 
 #, python-format
 msgid "%(detail)s"
index 8657e66..5967192 100644 (file)
@@ -3,21 +3,22 @@
 # This file is distributed under the same license as the keystone project.
 #
 # Translators:
+# OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: Keystone\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-08-06 06:28+0000\n"
-"PO-Revision-Date: 2014-08-31 15:19+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
+"PO-Revision-Date: 2014-08-31 03:19+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: French (http://www.transifex.com/openstack/keystone/language/"
-"fr/)\n"
+"Language-Team: French\n"
 "Language: fr\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"Generated-By: Babel 2.0\n"
+"X-Generator: Zanata 3.7.1\n"
 
 #, python-format
 msgid "Unable to open template file %s"
index 5ddd639..0339cac 100644 (file)
@@ -8,19 +8,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 8.0.0.0b4.dev56\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-21 06:08+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-06-26 05:13+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: French (http://www.transifex.com/openstack/keystone/language/"
-"fr/)\n"
+"Language-Team: French\n"
 "Language: fr\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"Generated-By: Babel 2.0\n"
 "X-Generator: Zanata 3.7.1\n"
 
 #, python-format
index 08cee0e..37ef89e 100644 (file)
@@ -6,21 +6,22 @@
 # Bruno Cornec <bruno.cornec@hp.com>, 2014
 # Maxime COQUEREL <max.coquerel@gmail.com>, 2014
 # Andrew Melim <nokostya.translation@gmail.com>, 2014
+# OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: Keystone\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-08-06 06:28+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-08-01 06:26+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: French (http://www.transifex.com/openstack/keystone/language/"
-"fr/)\n"
+"Language-Team: French\n"
 "Language: fr\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"Generated-By: Babel 2.0\n"
+"X-Generator: Zanata 3.7.1\n"
 
 #, python-format
 msgid ""
index d2fddf2..6eb0783 100644 (file)
@@ -5,21 +5,22 @@
 # Translators:
 # Bruno Cornec <bruno.cornec@hp.com>, 2014
 # Maxime COQUEREL <max.coquerel@gmail.com>, 2014
+# OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: Keystone\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-08-06 06:28+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-07-29 06:04+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: French (http://www.transifex.com/openstack/keystone/language/"
-"fr/)\n"
+"Language-Team: French\n"
 "Language: fr\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"Generated-By: Babel 2.0\n"
+"X-Generator: Zanata 3.7.1\n"
 
 #, python-format
 msgid "%s is not a dogpile.proxy.ProxyBackend"
index b2aff55..9fb2b2e 100644 (file)
 # Tom Cocozzello <tjcocozz@us.ibm.com>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 9.0.0.dev14\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-24 06:09+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-09-03 12:54+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: French (http://www.transifex.com/openstack/keystone/language/"
-"fr/)\n"
+"Language: fr\n"
+"Language-Team: French\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 2.0\n"
+"Generated-By: Babel 2.1.1\n"
 
 #, python-format
 msgid "%(detail)s"
index 102329f..b45fc0d 100644 (file)
@@ -3,21 +3,22 @@
 # This file is distributed under the same license as the keystone project.
 #
 # Translators:
+# OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: Keystone\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-08-06 06:28+0000\n"
-"PO-Revision-Date: 2014-08-31 15:19+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
+"PO-Revision-Date: 2014-08-31 03:19+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Hungarian (http://www.transifex.com/openstack/keystone/"
-"language/hu/)\n"
+"Language-Team: Hungarian\n"
 "Language: hu\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Generated-By: Babel 2.0\n"
+"X-Generator: Zanata 3.7.1\n"
 
 #, python-format
 msgid "Unable to open template file %s"
index db15042..317cdc8 100644 (file)
@@ -3,21 +3,22 @@
 # This file is distributed under the same license as the keystone project.
 #
 # Translators:
+# OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: Keystone\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-08-06 06:28+0000\n"
-"PO-Revision-Date: 2014-08-31 15:19+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
+"PO-Revision-Date: 2014-08-31 03:19+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Italian (http://www.transifex.com/openstack/keystone/language/"
-"it/)\n"
+"Language-Team: Italian\n"
 "Language: it\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Generated-By: Babel 2.0\n"
+"X-Generator: Zanata 3.7.1\n"
 
 #, python-format
 msgid "Unable to open template file %s"
index 085f3b3..e60a6d8 100644 (file)
@@ -7,18 +7,18 @@
 # Tom Cocozzello <tjcocozz@us.ibm.com>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 9.0.0.dev14\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-24 06:09+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-09-03 12:54+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Italian (http://www.transifex.com/openstack/keystone/language/"
-"it/)\n"
+"Language: it\n"
+"Language-Team: Italian\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 2.0\n"
+"Generated-By: Babel 2.1.1\n"
 
 #, python-format
 msgid "%(detail)s"
index e5ec307..9337f92 100644 (file)
@@ -3,21 +3,22 @@
 # This file is distributed under the same license as the keystone project.
 #
 # Translators:
+# Akihiro Motoki <amotoki@gmail.com>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: Keystone\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-08-06 06:28+0000\n"
-"PO-Revision-Date: 2014-08-31 15:19+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
+"PO-Revision-Date: 2014-08-31 03:19+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Japanese (http://www.transifex.com/openstack/keystone/"
-"language/ja/)\n"
+"Language-Team: Japanese\n"
 "Language: ja\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
+"Generated-By: Babel 2.0\n"
+"X-Generator: Zanata 3.7.1\n"
 
 #, python-format
 msgid "Unable to open template file %s"
index 639a243..541eda9 100644 (file)
@@ -4,22 +4,21 @@
 #
 # Translators:
 # Tomoyuki KATO <tomo@dream.daynight.jp>, 2012-2013
-# OpenStack Infra <zanata@openstack.org>, 2015. #zanata
-# Tom Cocozzello <tjcocozz@us.ibm.com>, 2015. #zanata
+# Akihiro Motoki <amotoki@gmail.com>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 9.0.0.dev14\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-24 06:09+0000\n"
-"PO-Revision-Date: 2015-09-03 12:54+0000\n"
-"Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Japanese (http://www.transifex.com/openstack/keystone/"
-"language/ja/)\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
+"PO-Revision-Date: 2015-09-27 10:27+0000\n"
+"Last-Translator: Akihiro Motoki <amotoki@gmail.com>\n"
+"Language: ja\n"
+"Language-Team: Japanese\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 2.0\n"
+"Generated-By: Babel 2.1.1\n"
 
 #, python-format
 msgid "%(detail)s"
@@ -34,7 +33,7 @@ msgstr ""
 
 #, python-format
 msgid "%(host)s is not a trusted dashboard host"
-msgstr "%(host)s はトラステッド・ダッシュボード・ホストではありません"
+msgstr "%(host)s は信頼されたダッシュボードホストではありません"
 
 #, python-format
 msgid "%(message)s %(amendment)s"
@@ -45,13 +44,13 @@ msgid ""
 "%(mod_name)s doesn't provide database migrations. The migration repository "
 "path at %(path)s doesn't exist or isn't a directory."
 msgstr ""
-"%(mod_name)s ã\81¯ã\83\87ã\83¼ã\82¿ã\83\99ã\83¼ã\82¹ã\83»ã\83\9eã\82¤ã\82°ã\83¬ã\83¼ã\82·ã\83§ã\83³ã\82\92æ\8f\90ä¾\9bã\81\97ã\81¦ã\81\84ã\81¾ã\81\9bã\82\93ã\80\82%(path)s ã\81®"
-"ã\83\9eã\82¤ã\82°ã\83¬ã\83¼ã\82·ã\83§ã\83³ã\83»ã\83ªã\83\9dã\82¸ã\83\88ã\83ªã\83¼ã\83»ã\83\91ã\82¹ã\81¯å­\98å\9c¨ã\81\97ã\81ªã\81\84ã\81\8bã\80\81ã\81¾ã\81\9fã\81¯ã\83\87ã\82£ã\83¬ã\82¯ã\83\88ã\83ªã\83¼ã\81§ã\81¯"
-"ã\81\82ã\82\8aã\81¾ã\81\9bã\82\93。"
+"%(mod_name)s ã\81¯ã\83\87ã\83¼ã\82¿ã\83\99ã\83¼ã\82¹ã\83\9eã\82¤ã\82°ã\83¬ã\83¼ã\82·ã\83§ã\83³ã\82\92æ\8f\90ä¾\9bã\81\97ã\81¦ã\81\84ã\81¾ã\81\9bã\82\93ã\80\82%(path)s ã\81®ã\83\9e"
+"ã\82¤ã\82°ã\83¬ã\83¼ã\82·ã\83§ã\83³ã\83ªã\83\9dã\82¸ã\83\88ã\83ªã\83¼ã\81®ã\83\91ã\82¹ã\81\8cå­\98å\9c¨ã\81\97ã\81ªã\81\84ã\81\8bã\80\81ã\83\87ã\82£ã\83¬ã\82¯ã\83\88ã\83ªã\83¼ã\81§ã\81¯ã\81ªã\81\84ã\81\8bã\81®ã\81\84"
+"ã\81\9aã\82\8cã\81\8bã\81§ã\81\99。"
 
 #, python-format
 msgid "%(property_name)s cannot be less than %(min_length)s characters."
-msgstr "%(property_name)s は %(min_length)s 文字より小さくできません。"
+msgstr "%(property_name)s は %(min_length)s 文字よりくできません。"
 
 #, python-format
 msgid "%(property_name)s is not a %(display_expected_type)s"
@@ -59,11 +58,11 @@ msgstr "%(property_name)s が %(display_expected_type)s ではありません。
 
 #, python-format
 msgid "%(property_name)s should not be greater than %(max_length)s characters."
-msgstr "%(property_name)s は %(max_length)s 文字より大きくできません。"
+msgstr "%(property_name)s は %(max_length)s 文字よりくできません。"
 
 #, python-format
 msgid "%s cannot be empty."
-msgstr "%s は空にできません。"
+msgstr "%s ã\81¯ç©ºã\81«ã\81¯ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82"
 
 #, python-format
 msgid "%s extension does not exist."
@@ -71,55 +70,55 @@ msgstr "%s 拡張が存在しません。"
 
 #, python-format
 msgid "%s field is required and cannot be empty"
-msgstr "%s フィールドは必須フィールドであるため、空にできません"
+msgstr "フィールド %s は必須フィールドであるため、空にできません"
 
 #, python-format
 msgid "%s field(s) cannot be empty"
-msgstr "%s フィールドを空にすることはできません"
+msgstr "フィールド %s を空にすることはできません"
 
 msgid "(Disable debug mode to suppress these details.)"
-msgstr "(これらの詳細を抑制するには、デバッグ・モードを無効にします。)"
+msgstr "(これらの詳細出力を抑制するには、デバッグモードを無効にします。)"
 
 msgid "--all option cannot be mixed with other options"
 msgstr "--all オプションを他のオプションと組み合わせて使用することはできません"
 
 msgid "A project-scoped token is required to produce a service catalog."
 msgstr ""
-"ã\82µã\83¼ã\83\93ã\82¹ã\83»ã\82«ã\82¿ã\83­ã\82°ã\82\92ç\94\9fæ\88\90ã\81\99ã\82\8bã\81«ã\81¯ã\80\81ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88ã\81«ã\82¹ã\82³ã\83¼ã\83\97宣è¨\80されたトークンが"
+"ã\82µã\83¼ã\83\93ã\82¹ã\82«ã\82¿ã\83­ã\82°ã\82\92ç\94\9fæ\88\90ã\81\99ã\82\8bã\81«ã\81¯ã\80\81ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88ã\81«ã\82¹ã\82³ã\83¼ã\83\97ã\81\8c設å®\9aされたトークンが"
 "必要です。"
 
 msgid "Access token is expired"
-msgstr "ã\82¢ã\82¯ã\82»ã\82¹ã\83»ã\83\88ã\83¼ã\82¯ã\83³ã\81®æ\9c\89å\8a¹æ\9c\9fé\99\90ã\81\8cå\88\87ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99"
+msgstr "アクセストークンの有効期限が切れています"
 
 msgid "Access token not found"
-msgstr "ã\82¢ã\82¯ã\82»ã\82¹ã\83»ã\83\88ã\83¼ã\82¯ã\83³ã\81\8cè¦\8bã\81¤ã\81\8bã\82\8aã\81¾ã\81\9bã\82\93"
+msgstr "アクセストークンが見つかりません"
 
 msgid "Additional authentications steps required."
 msgstr "追加認証手順が必要です。"
 
 msgid "An unexpected error occurred when retrieving domain configs"
-msgstr "ドメイン構成の取得中に予期しないエラーが発生しました"
+msgstr "ドメイン設定の取得中に予期しないエラーが発生しました"
 
 #, python-format
 msgid "An unexpected error occurred when trying to store %s"
-msgstr "%s ã\82\92ä¿\9d管ã\81\97ã\82\88ã\81\86ã\81¨è©¦ã\81¿ã\81¦ã\81\84ã\82\8bã\81¨ã\81\8dã\81«ã\80\81予期しないエラーが発生しました"
+msgstr "%s ã\81®ä¿\9då­\98中ã\81«予期しないエラーが発生しました"
 
 msgid "An unexpected error prevented the server from fulfilling your request."
-msgstr "äº\88æ\9c\9fã\81\97ã\81ªã\81\84ã\82¨ã\83©ã\83¼ã\81\8cç\99ºç\94\9fã\81\97ã\81\9fã\81\9fã\82\81ã\80\81ã\82µã\83¼ã\83\90ã\83¼ã\81¯è¦\81æ±\82ã\82\92æº\80ã\81\9fã\81\99ã\81\93ã\81¨ã\81\8c"
+msgstr "äº\88æ\9c\9fã\81\97ã\81ªã\81\84ã\82¨ã\83©ã\83¼ã\81\8cç\99ºç\94\9fã\81\97ã\81\9fã\81\9fã\82\81ã\80\81ã\82µã\83¼ã\83\90ã\83¼ã\81\8cè¦\81æ±\82ã\82\92å®\8cäº\86ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\81§ã\81\97ã\81\9fã\80\82"
 
 #, python-format
 msgid ""
 "An unexpected error prevented the server from fulfilling your request: "
 "%(exception)s"
 msgstr ""
-"äº\88æ\9c\9fã\81\97ã\81ªã\81\84ã\82¨ã\83©ã\83¼ã\81\8cç\99ºç\94\9fã\81\97ã\81\9fã\81\9fã\82\81ã\80\81ã\82µã\83¼ã\83\90ã\83¼ã\81¯è¦\81æ±\82ã\82\92æº\80ã\81\9fã\81\99ã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\81§ã\81\97"
-"た:  %(exception)s"
+"äº\88æ\9c\9fã\81\97ã\81ªã\81\84ã\82¨ã\83©ã\83¼ã\81\8cç\99ºç\94\9fã\81\97ã\81\9fã\81\9fã\82\81ã\80\81ã\82µã\83¼ã\83\90ã\83¼ã\81\8cè¦\81æ±\82ã\82\92å®\8cäº\86ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\81§ã\81\97ã\81\9f:  "
+"%(exception)s"
 
 msgid "An unhandled exception has occurred: Could not find metadata."
-msgstr "未処理例外が発生しました。メタデータが見つかりませんでした。"
+msgstr "処理できない例外が発生しました。メタデータが見つかりませんでした。"
 
 msgid "At least one option must be provided"
-msgstr "オプションを少なくとも 1 つは指定する必要があります"
+msgstr "少なくとも 1 つはオプションを指定する必要があります"
 
 msgid "At least one option must be provided, use either --all or --domain-name"
 msgstr ""
@@ -127,7 +126,7 @@ msgstr ""
 "name を使用してください"
 
 msgid "At least one role should be specified."
-msgstr "少なくとも 1 つの役割を指定する必要があります。"
+msgstr "少なくとも 1 つのロールを指定する必要があります。"
 
 msgid "Attempted to authenticate with an unsupported method."
 msgstr "サポートされていないメソッドを使用して認証を行おうとしました。"
@@ -140,7 +139,7 @@ msgstr ""
 "証を使用してください"
 
 msgid "Authentication plugin error."
-msgstr "èª\8d証ã\83\97ã\83©ã\82°ã\82¤ã\83³ã\83»ã\82¨ã\83©ã\83¼ã\80\82"
+msgstr "認証プラグインエラー。"
 
 msgid "Cannot authorize a request token with a token issued via delegation."
 msgstr ""
@@ -154,6 +153,7 @@ msgstr "%(option_name)s %(attr)s を変更できません"
 msgid "Cannot change Domain ID"
 msgstr "ドメイン ID を変更できません"
 
+#, fuzzy
 msgid "Cannot change consumer secret"
 msgstr "コンシューマーの秘密を変更できません"
 
@@ -163,7 +163,7 @@ msgstr "ユーザー ID を変更できません"
 msgid "Cannot change user name"
 msgstr "ユーザー名を変更できません"
 
-#, python-format
+#, fuzzy, python-format
 msgid "Cannot create project with parent: %(project_id)s"
 msgstr "親を持つプロジェクトを作成できません: %(project_id)s"
 
@@ -184,44 +184,48 @@ msgstr "証明書 %(cert_file)s を開くことができません。理由: %(re
 msgid "Cannot remove role that has not been granted, %s"
 msgstr "許可されていないロールを削除できません、%s"
 
+#, fuzzy
 msgid ""
 "Cannot truncate a driver call without hints list as first parameter after "
 "self "
 msgstr ""
-"ã\82»ã\83«ã\83\95ã\81®å¾\8cã\81«æ\9c\80å\88\9dã\81®ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\83¼ã\81¨ã\81\97ã\81¦ã\83\92ã\83³ã\83\88ã\83»ã\83ªã\82¹ã\83\88ã\81ªã\81\97ã\81§ã\83\89ã\83©ã\82¤ã\83\90ã\83¼å\91¼ã\81³å\87ºã\81\97ã\82\92"
-"り捨てることはできません"
+"ã\82»ã\83«ã\83\95ã\81®å¾\8cã\81«æ\9c\80å\88\9dã\81®ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\83¼ã\81¨ã\81\97ã\81¦ã\83\92ã\83³ã\83\88ã\83ªã\82¹ã\83\88ã\81ªã\81\97ã\81§ã\83\89ã\83©ã\82¤ã\83\90ã\83¼å\91¼ã\81³å\87ºã\81\97ã\82\92å\88\87"
+"り捨てることはできません"
 
 msgid ""
 "Cannot use parents_as_list and parents_as_ids query params at the same time."
 msgstr ""
-"照会パラメーター parents_as_list と parents_as_ids を併用することはできませ"
-"ん。"
+"問い合わせパラメーター parents_as_list と parents_as_ids を同時に使用すること"
+"ã\81¯ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82"
 
 msgid ""
 "Cannot use subtree_as_list and subtree_as_ids query params at the same time."
 msgstr ""
-"照会パラメーター subtree_as_list と subtree_as_ids を併用することはできませ"
-"ん。"
+"問い合わせパラメーター subtree_as_list と subtree_as_ids を同時に使用すること"
+"ã\81¯ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82"
 
+#, fuzzy
 msgid ""
 "Combining effective and group filter will always result in an empty list."
 msgstr ""
-"æ\9c\89å\8a¹ã\83\95ã\82£ã\83«ã\82¿ã\83¼ã\81¨ã\82°ã\83«ã\83¼ã\83\97ã\83»ã\83\95ã\82£ã\83«ã\82¿ã\83¼ã\81®çµ\84ã\81¿å\90\88ã\82\8fã\81\9bã\81¯å¸¸ã\81«ç©ºã\81®ã\83ªã\82¹ã\83\88ã\81«ã\81ªã\82\8aã\81¾ã\81\99ã\80\82"
+"有効フィルターとグループフィルターの組み合わせは常に空のリストになります。"
 
+#, fuzzy
 msgid ""
 "Combining effective, domain and inherited filters will always result in an "
 "empty list."
 msgstr ""
-"æ\9c\89å\8a¹ã\83\95ã\82£ã\83«ã\82¿ã\83¼ã\80\81ã\83\89ã\83¡ã\82¤ã\83³ã\83»ã\83\95ã\82£ã\83«ã\82¿ã\83¼ã\80\81ã\81\8aã\82\88ã\81³ç¶\99æ\89¿ã\83\95ã\82£ã\83«ã\82¿ã\83¼ã\81®çµ\84ã\81¿å\90\88ã\82\8fã\81\9bã\81¯å¸¸ã\81«"
-"のリストになります。"
+"æ\9c\89å\8a¹ã\83\95ã\82£ã\83«ã\82¿ã\83¼ã\80\81ã\83\89ã\83¡ã\82¤ã\83³ã\83\95ã\82£ã\83«ã\82¿ã\83¼ã\80\81ã\81\8aã\82\88ã\81³ç¶\99æ\89¿ã\83\95ã\82£ã\83«ã\82¿ã\83¼ã\81®çµ\84ã\81¿å\90\88ã\82\8fã\81\9bã\81¯å¸¸ã\81«ç©º"
+"のリストになります。"
 
 #, python-format
 msgid "Conflict occurred attempting to store %(type)s - %(details)s"
-msgstr "%(type)s を保するときに競合が発生しました - %(details)s"
+msgstr "%(type)s を保するときに競合が発生しました - %(details)s"
 
 #, python-format
 msgid "Conflicting region IDs specified: \"%(url_id)s\" != \"%(ref_id)s\""
-msgstr "矛盾する領域 ID が指定されました: \"%(url_id)s\" != \"%(ref_id)s\""
+msgstr ""
+"矛盾するリージョン ID が指定されました: \"%(url_id)s\" != \"%(ref_id)s\""
 
 msgid "Consumer not found"
 msgstr "コンシューマーが見つかりません"
@@ -230,44 +234,45 @@ msgstr "コンシューマーが見つかりません"
 msgid ""
 "Could not change immutable attribute(s) '%(attributes)s' in target %(target)s"
 msgstr ""
-"ターゲット %(target)s で不変の属性 '%(attributes)s' を変更できませんでした"
+"ターゲット %(target)s の変更不可の属性 '%(attributes)s' を変更できませんでし"
+"た"
 
 #, python-format
 msgid ""
 "Could not find %(group_or_option)s in domain configuration for domain "
 "%(domain_id)s"
 msgstr ""
-"%(group_or_option)s がドメイン %(domain_id)s のドメイン構成に見つかりませんで"
+"%(group_or_option)s がドメイン %(domain_id)s のドメイン設定に見つかりませんで"
 "した"
 
 #, python-format
 msgid "Could not find Endpoint Group: %(endpoint_group_id)s"
-msgstr "ã\82¨ã\83³ã\83\89ã\83\9dã\82¤ã\83³ã\83\88ã\83»ã\82°ã\83«ã\83¼ã\83\97ã\81\8cè¦\8bã\81¤ã\81\8bã\82\8aã\81¾ã\81\9bã\82\93ã\81§ã\81\97ã\81\9f: %(endpoint_group_id)s"
+msgstr "ã\82¨ã\83³ã\83\89ã\83\9dã\82¤ã\83³ã\83\88ã\82°ã\83«ã\83¼ã\83\97 %(endpoint_group_id)s ã\81\8cè¦\8bã\81¤ã\81\8bã\82\8aã\81¾ã\81\9bã\82\93ã\81§ã\81\97ã\81\9f"
 
 msgid "Could not find Identity Provider identifier in environment"
-msgstr "Identity Provider ID が環境内に見つかりませんでした"
+msgstr "Identity Provider ID が環境情報内に見つかりませんでした"
 
 #, python-format
 msgid "Could not find Identity Provider: %(idp_id)s"
-msgstr "ID プロバイダーが見つかりませんでした: %(idp_id)s"
+msgstr "ID プロバイダー %(idp_id)s が見つかりませんでした"
 
 #, python-format
 msgid "Could not find Service Provider: %(sp_id)s"
-msgstr "ã\82µã\83¼ã\83\93ã\82¹ã\83»ã\83\97ã\83­ã\83\90ã\82¤ã\83\80ã\83¼ %(sp_id)s ã\81\8cè¦\8bã\81¤ã\81\8bã\82\8aã\81¾ã\81\9bã\82\93ã\81§ã\81\97ã\81\9f"
+msgstr "サービスプロバイダー %(sp_id)s が見つかりませんでした"
 
-#, python-format
+#, fuzzy, python-format
 msgid "Could not find credential: %(credential_id)s"
 msgstr "資格情報が見つかりませんでした: %(credential_id)s"
 
 #, python-format
 msgid "Could not find domain: %(domain_id)s"
-msgstr "ドメインが見つかりませんでした: %(domain_id)s"
+msgstr "ドメイン %(domain_id)s が見つかりませんでした"
 
 #, python-format
 msgid "Could not find endpoint: %(endpoint_id)s"
-msgstr "エンドポイントが見つかりませんでした: %(endpoint_id)s"
+msgstr "エンドポイント %(endpoint_id)sが見つかりませんでした"
 
-#, python-format
+#, fuzzy, python-format
 msgid ""
 "Could not find federated protocol %(protocol_id)s for Identity Provider: "
 "%(idp_id)s"
@@ -277,69 +282,70 @@ msgstr ""
 
 #, python-format
 msgid "Could not find group: %(group_id)s"
-msgstr "グループが見つかりませんでした: %(group_id)s"
+msgstr "グループ %(group_id)s が見つかりませんでした"
 
 #, python-format
 msgid "Could not find mapping: %(mapping_id)s"
-msgstr "マッピングが見つかりませんでした: %(mapping_id)s"
+msgstr "マッピング %(mapping_id)s が見つかりませんでした"
 
 msgid "Could not find policy association"
 msgstr "ポリシー関連付けが見つかりませんでした"
 
 #, python-format
 msgid "Could not find policy: %(policy_id)s"
-msgstr "ポリシーが見つかりませんでした: %(policy_id)s"
+msgstr "ポリシー %(policy_id)s が見つかりませんでした"
 
 #, python-format
 msgid "Could not find project: %(project_id)s"
-msgstr "プロジェクトが見つかりませんでした: %(project_id)s"
+msgstr "プロジェクト %(project_id)s が見つかりませんでした"
 
 #, python-format
 msgid "Could not find region: %(region_id)s"
-msgstr "領域が見つかりませんでした: %(region_id)s"
+msgstr "リージョン %(region_id)s が見つかりませんでした"
 
 msgid "Could not find role"
-msgstr "役割が見つかりませんでした"
+msgstr "ロールが見つかりませんでした"
 
 #, python-format
 msgid ""
 "Could not find role assignment with role: %(role_id)s, user or group: "
 "%(actor_id)s, project or domain: %(target_id)s"
 msgstr ""
-"役割 %(role_id)s を持つ割り当てが見つかりませんでした。ユーザーまたはグルー"
-"プ: %(actor_id)s、プロジェクトまたはドメイン: %(target_id)s"
+"ロール %(role_id)s を持つ割り当てが見つかりませんでした。ユーザーまたはグルー"
+"プは %(actor_id)s で、プロジェクトまたはドメインが %(target_id)s です"
 
 #, python-format
 msgid "Could not find role: %(role_id)s"
-msgstr "役割が見つかりませんでした: %(role_id)s"
+msgstr "ロール %(role_id)s が見つかりませんでした"
 
 #, python-format
 msgid "Could not find service: %(service_id)s"
-msgstr "サービスが見つかりませんでした: %(service_id)s"
+msgstr "サービス %(service_id)s が見つかりませんでした"
 
 #, python-format
 msgid "Could not find token: %(token_id)s"
-msgstr "トークンが見つかりませんでした: %(token_id)s"
+msgstr "トークン %(token_id)s が見つかりませんでした"
 
 #, python-format
 msgid "Could not find trust: %(trust_id)s"
-msgstr "トラストが見つかりませんでした: %(trust_id)s"
+msgstr "トラスト %(trust_id)s が見つかりませんでした"
 
 #, python-format
 msgid "Could not find user: %(user_id)s"
-msgstr "ユーザーが見つかりませんでした: %(user_id)s"
+msgstr "ユーザー %(user_id)s が見つかりませんでした:"
 
 #, python-format
 msgid "Could not find version: %(version)s"
-msgstr "バージョンが見つかりませんでした: %(version)s"
+msgstr "バージョン %(version)s が見つかりませんでした"
 
 #, python-format
 msgid "Could not find: %(target)s"
-msgstr "見つかりませんでした: %(target)s"
+msgstr "%(target)s が見つかりませんでした"
 
 msgid "Could not validate the access token"
-msgstr "ã\82¢ã\82¯ã\82»ã\82¹ã\83»ã\83\88ã\83¼ã\82¯ã\83³ã\82\92æ¤\9c証ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\81§ã\81\97ã\81\9f"
+msgstr "アクセストークンを検証できませんでした"
 
+#, fuzzy
 msgid "Credential belongs to another user"
 msgstr "資格情報が別のユーザーに属しています"
 
@@ -349,7 +355,8 @@ msgstr "/domains/%s/config のデータベース"
 
 msgid ""
 "Disabling an entity where the 'enable' attribute is ignored by configuration."
-msgstr "「enable」属性が構成によって無視されているエンティティーを無効化中。"
+msgstr ""
+"「enable」属性が設定によって無視されているエンティティーを無効化中です。"
 
 #, python-format
 msgid "Domain (%s)"
@@ -365,24 +372,24 @@ msgstr "ドメインに %s という ID を付けることはできません"
 
 #, python-format
 msgid "Domain is disabled: %s"
-msgstr "ドメインが無効化されています: %s"
+msgstr "ドメイン %s が無効になっています"
 
 msgid "Domain metadata not supported by LDAP"
-msgstr "ã\83\89ã\83¡ã\82¤ã\83³ã\83»ã\83¡ã\82¿ã\83\87ã\83¼ã\82¿ã\81¯ LDAP ã\81§ã\81¯ã\82µã\83\9dã\83¼ã\83\88ã\81\95ã\82\8cã\81¾ã\81\9bã\82\93"
+msgstr "ドメインメタデータは LDAP ではサポートされません"
 
 msgid "Domain scoped token is not supported"
-msgstr "ドメインをスコープにしたトークンはサポートされません"
+msgstr "ã\83\89ã\83¡ã\82¤ã\83³ã\82\92ã\82¹ã\82³ã\83¼ã\83\97ã\81«ã\81\97ã\81\9fã\83\88ã\83¼ã\82¯ã\83³ã\81¯ã\82µã\83\9dã\83¼ã\83\88ã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\9bã\82\93"
 
 #, python-format
 msgid ""
 "Domain: %(domain)s already has a configuration defined - ignoring file: "
 "%(file)s."
 msgstr ""
-"ドメイン %(domain)s には既に構成があります - ファイル %(file)s は無視されま"
-"す。"
+"ドメイン %(domain)s には既に定義された設定があります。ファイル %(file)s は無"
+"視されます。"
 
 msgid "Domains are read-only against LDAP"
-msgstr "ドメインが LDAP に対して読み取り専用です"
+msgstr "LDAP の場合はドメインは読み取り専用です"
 
 msgid "Duplicate Entry"
 msgstr "重複する項目"
@@ -404,37 +411,37 @@ msgstr "「有効」フィールドはブール値でなければなりません
 #, python-format
 msgid "Endpoint %(endpoint_id)s not found in project %(project_id)s"
 msgstr ""
-"ã\82¨ã\83³ã\83\89ã\83\9dã\82¤ã\83³ã\83\88 %(endpoint_id)s ã\81¯プロジェクト %(project_id)s に見つかりません"
+"ã\82¨ã\83³ã\83\89ã\83\9dã\82¤ã\83³ã\83\88 %(endpoint_id)s ã\81\8cプロジェクト %(project_id)s に見つかりません"
 
 msgid "Endpoint Group Project Association not found"
-msgstr "ã\82¨ã\83³ã\83\89ã\83\9dã\82¤ã\83³ã\83\88ã\83»ã\82°ã\83«ã\83¼ã\83\97ã\83»ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88関連付けが見つかりません"
+msgstr "ã\82¨ã\83³ã\83\89ã\83\9dã\82¤ã\83³ã\83\88ã\82°ã\83«ã\83¼ã\83\97ã\81¨ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88ã\81®関連付けが見つかりません"
 
 msgid "Ensure configuration option idp_entity_id is set."
-msgstr "構成オプション idp_entity_id が設定されていることを確認してください。"
+msgstr "設定オプション idp_entity_id が設定されていることを確認してください。"
 
 msgid "Ensure configuration option idp_sso_endpoint is set."
 msgstr ""
-"構成オプション idp_sso_endpoint が設定されていることを確認してください。"
+"設定オプション idp_sso_endpoint が設定されていることを確認してください。"
 
 #, python-format
 msgid ""
 "Error parsing configuration file for domain: %(domain)s, file: %(file)s."
 msgstr ""
-"構成ファイルの構文解析エラー。ドメイン: %(domain)s、ファイル: %(file)s。"
+"ドメイン: %(domain)s、ファイル: %(file)s の設定ファイルの構文解析エラー。"
 
 #, python-format
 msgid "Error while reading metadata file, %(reason)s"
-msgstr "ã\83¡ã\82¿ã\83\87ã\83¼ã\82¿ã\83»ã\83\95ã\82¡ã\82¤ã\83«ã\81®èª­ã\81¿å\8f\96ã\82\8a中ã\81«ã\82¨ã\83©ã\83¼ã\81\8cç\99ºç\94\9fã\81\97ã\81¾ã\81\97ã\81\9fã\80\82%(reason)s"
+msgstr "メタデータファイルの読み取り中にエラーが発生しました。%(reason)s"
 
 #, python-format
 msgid "Expected dict or list: %s"
-msgstr "期待される辞書または一覧: %s"
+msgstr "期待される辞書またはリスト: %s"
 
 msgid ""
 "Expected signing certificates are not available on the server. Please check "
 "Keystone configuration."
 msgstr ""
-"予期された署名証明書がサーバーにありません。Keystone の構成を確認してくださ"
+"想定された署名証明書がサーバーにありません。Keystone の設定を確認してくださ"
 "い。"
 
 #, python-format
@@ -443,17 +450,18 @@ msgid ""
 "with the request since it is either malformed or otherwise incorrect. The "
 "client is assumed to be in error."
 msgstr ""
-"%(target)s ã\81§ %(attribute)s ã\81\8cæ¤\9cå\87ºã\81\95ã\82\8cã\82\8bã\81\93ã\81¨ã\81\8cäº\88æ\9c\9fã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99ã\80\82è¦\81æ±\82ã\81®å½¢å¼\8fã\81\8c"
-"誤っているか、または要求が正しくないため、サーバーは要求に従うことができませ"
-"ã\82\93ã\81§ã\81\97ã\81\9fã\80\82ã\82¯ã\83©ã\82¤ã\82¢ã\83³ã\83\88ã\81§ã\82¨ã\83©ã\83¼ã\81\8cç\99ºç\94\9fã\81\97ã\81¦ã\81\84ã\82\8bã\81¨è¦\8bã\81ªã\81\95れます。"
+"%(target)s ã\81« %(attribute)s ã\81\8cã\81\82ã\82\8bã\81\93ã\81¨ã\81\8cæ\83³å®\9aã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99ã\80\82è¦\81æ±\82ã\81®å½¢å¼\8fã\81\8cä¸\8dæ­£ã\82\82"
+"しくは正しくないため、サーバーは要求に応じることができませんでした。クライア"
+"ã\83³ã\83\88ã\81§ã\82¨ã\83©ã\83¼ã\81\8cç\99ºç\94\9fã\81\97ã\81¦ã\81\84ã\82\8bã\81¨è\80\83ã\81\88ã\82\89れます。"
 
 #, python-format
 msgid "Failed to start the %(name)s server"
-msgstr "%(name)s サーバーの動に失敗しました"
+msgstr "%(name)s サーバーの動に失敗しました"
 
 msgid "Failed to validate token"
 msgstr "トークンの検証に失敗しました"
 
+#, fuzzy
 msgid "Federation token is expired"
 msgstr "連合トークンの有効期限が切れています"
 
@@ -462,33 +470,33 @@ msgid ""
 "Field \"remaining_uses\" is set to %(value)s while it must not be set in "
 "order to redelegate a trust"
 msgstr ""
-"フィールド「remaining_uses」が %(value)s に設定されていますが、トラストを再委"
-"任するにはこのフィールドを設定してはなりません"
+"フィールド \"remaining_uses\" は %(value)s になっていますが、トラストを再委任"
+"するにはこのフィールドが設定されていてはなりません"
 
 msgid "Found invalid token: scoped to both project and domain."
 msgstr ""
-"ç\84¡å\8a¹ã\81ªã\83\88ã\83¼ã\82¯ã\83³ã\81\8cè¦\8bã\81¤ã\81\8bã\82\8aã\81¾ã\81\97ã\81\9f: ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88ã\81¨ã\83\89ã\83¡ã\82¤ã\83³ã\81®ä¸¡æ\96¹ã\81«ã\82¹ã\82³ã\83¼ã\83\97宣è¨\80ã\81\95"
-"れています。"
+"ç\84¡å\8a¹ã\81ªã\83\88ã\83¼ã\82¯ã\83³ã\81\8cè¦\8bã\81¤ã\81\8bã\82\8aã\81¾ã\81\97ã\81\9f: ã\82¹ã\82³ã\83¼ã\83\97ã\81\8cã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88ã\81¨ã\83\89ã\83¡ã\82¤ã\83³ã\81®ä¸¡æ\96¹ã\81«å¯¾ã\81\97"
+"ã\81¦è¨­å®\9aã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99ã\80\82"
 
 #, python-format
 msgid "Group %(group)s is not supported for domain specific configurations"
-msgstr "ドメイン固有の構成ではグループ %(group)s はサポートされません"
+msgstr "ドメイン固有の設定ではグループ %(group)s はサポートされません"
 
 #, python-format
 msgid ""
 "Group %(group_id)s returned by mapping %(mapping_id)s was not found in the "
 "backend."
 msgstr ""
-"ã\83\9eã\83\83ã\83\94ã\83³ã\82° %(mapping_id)s ã\81«ã\82\88ã\81£ã\81¦è¿\94ã\81\95ã\82\8cã\81\9fã\82°ã\83«ã\83¼ã\83\97 %(group_id)s ã\81\8cã\83\90ã\83\83ã\82¯ã\82¨ã\83³"
-"ã\83\89ã\81«è¦\8bã\81¤ã\81\8bã\82\8aã\81¾ã\81\9bã\82\93ã\81§ã\81\97ã\81\9fã\80\82"
+"ã\83\9eã\83\83ã\83\94ã\83³ã\82° %(mapping_id)s ã\81\8cè¿\94ã\81\97ã\81\9fã\82°ã\83«ã\83¼ã\83\97 %(group_id)s ã\81\8cã\83\90ã\83\83ã\82¯ã\82¨ã\83³ã\83\89ã\81«ã\81\82ã\82\8a"
+"ませんでした。"
 
 #, python-format
 msgid ""
 "Group membership across backend boundaries is not allowed, group in question "
 "is %(group_id)s, user is %(user_id)s"
 msgstr ""
-"バックエンド境界を越えるグループ・メンバーシップは許可されません。問題となっ"
-"ているグループは %(group_id)s、ユーザーは %(user_id)s です"
+"バックエンド境界をまたぐグループメンバーシップは許可されていません。問題と"
+"ã\81ªã\81£ã\81¦ã\81\84ã\82\8bã\82°ã\83«ã\83¼ã\83\97ã\81¯ %(group_id)sã\80\81ã\83¦ã\83¼ã\82¶ã\83¼ã\81¯ %(user_id)s ã\81§ã\81\99"
 
 #, python-format
 msgid "ID attribute %(id_attr)s not found in LDAP object %(dn)s"
@@ -498,6 +506,7 @@ msgstr "ID 属性 %(id_attr)s が LDAP オブジェクト %(dn)s に見つかり
 msgid "Identity Provider %(idp)s is disabled"
 msgstr "ID プロバイダー %(idp)s は無効になっています"
 
+#, fuzzy
 msgid ""
 "Incoming identity provider identifier not included among the accepted "
 "identifiers."
@@ -506,30 +515,33 @@ msgstr "着信 ID プロバイダー ID が受諾 ID に含まれていません
 #, python-format
 msgid "Invalid LDAP TLS certs option: %(option)s. Choose one of: %(options)s"
 msgstr ""
-"LDAP TLS 証明書オプション %(option)s が無効です。以下のいずれかを選択してくだ"
-"さい: %(options)s"
+"無効な LDAP TLS 証明書オプション %(option)s です。 %(options)s のいずれかを選"
+"択してください"
 
 #, python-format
 msgid "Invalid LDAP TLS_AVAIL option: %s. TLS not available"
-msgstr "無効な LDAP TLS_AVAIL オプション: %s。TLS が利用できません。"
+msgstr "無効な LDAP TLS_AVAIL オプション %s です。TLS が利用できません。"
 
 #, python-format
 msgid "Invalid LDAP deref option: %(option)s. Choose one of: %(options)s"
 msgstr ""
-"LDAP deref オプションが無効です: %(option)s。%(options)s のいずれかを選択して"
-"ください"
+"無効な LDAP deref オプション %(option)s です。%(options)s のいずれかを選択し"
+"ã\81¦ã\81\8fã\81 ã\81\95ã\81\84"
 
 #, python-format
 msgid "Invalid LDAP scope: %(scope)s. Choose one of: %(options)s"
-msgstr "無効な LDAP 範囲: %(scope)s。次のどれかを選んでください: %(options)s"
+msgstr ""
+"無効な LDAP スコープ %(scope)s です。 %(options)s のいずれかを選んでくださ"
+"い: "
 
 msgid "Invalid TLS / LDAPS combination"
-msgstr "無効な TLS / LDAPS の組み合わせ"
+msgstr "無効な TLS / LDAPS の組み合わせです"
 
 #, python-format
 msgid "Invalid audit info data type: %(data)s (%(type)s)"
-msgstr "ç\84¡å\8a¹ã\81ªç\9b£æ\9f»æ\83\85å ±ã\83\87ã\83¼ã\82¿ã\83»ã\82¿ã\82¤ã\83\97: %(data)s (%(type)s)"
+msgstr "ç\84¡å\8a¹ã\81ªç\9b£æ\9f»æ\83\85å ±ã\83\87ã\83¼ã\82¿ã\82¿ã\82¤ã\83\97 %(data)s (%(type)s) ã\81§ã\81\99"
 
+#, fuzzy
 msgid "Invalid blob in credential"
 msgstr "資格情報内の blob が無効です"
 
@@ -538,17 +550,18 @@ msgid ""
 "Invalid domain name: %(domain)s found in config file name: %(file)s - "
 "ignoring this file."
 msgstr ""
-"無効なドメイン・ネーム %(domain)s が構成ファイル名 %(file)s に見つかりました "
-"- このファイルは無視されます。"
+"無効なドメイン名 %(domain)s が設定ファイル名 %(file)s に見つかりました。この"
+"ファイルは無視されます。"
 
 #, python-format
 msgid "Invalid domain specific configuration: %(reason)s"
-msgstr "ドメイン固有の構成が無効です: %(reason)s"
+msgstr "無効なドメイン固有の設定です: %(reason)s"
 
 #, python-format
 msgid "Invalid input for field '%(path)s'. The value is '%(value)s'."
 msgstr "フィールド '%(path)s' の入力が無効です。値は '%(value)s' です。"
 
+#, fuzzy
 msgid "Invalid limit value"
 msgstr "制限値が無効です"
 
@@ -585,13 +598,13 @@ msgid "Invalid user / password"
 msgstr "ユーザー/パスワードが無効です"
 
 msgid "Invalid username or password"
-msgstr "ç\84¡å\8a¹ã\81ªã\83¦ã\83¼ã\82¶ã\83¼å\90\8dã\81¾ã\81\9fã\81¯パスワード"
+msgstr "ç\84¡å\8a¹ã\81ªã\83¦ã\83¼ã\82¶ã\83¼å\90\8dã\81\8bパスワード"
 
 #, python-format
 msgid "KVS region %s is already configured. Cannot reconfigure."
 msgstr "KVS 領域 %s は既に構成されています。再構成はできません。"
 
-#, python-format
+#, fuzzy, python-format
 msgid "Key Value Store not configured: %s"
 msgstr "キー値ストアが構成されていません: %s"
 
@@ -609,19 +622,18 @@ msgstr "LDAP %s の更新"
 
 #, python-format
 msgid "Lock Timeout occurred for key, %(target)s"
-msgstr "ã\82­ã\83¼ %(target)s ã\81«ã\81¤ã\81\84ã\81¦ã\83­ã\83\83ã\82¯ã\83»ã\82¿ã\82¤ã\83 ã\82¢ã\82¦ã\83\88ã\81\8cç\99ºç\94\9fã\81\97ã\81¾ã\81\97ã\81\9f"
+msgstr "キー %(target)s についてロックタイムアウトが発生しました"
 
 #, python-format
 msgid "Lock key must match target key: %(lock)s != %(target)s"
 msgstr ""
-"ロック・キーがターゲット・キーと一致しなければなりません: %(lock)s != "
-"%(target)s"
+"ロックキーはターゲットキーと一致しなければなりません: %(lock)s != %(target)s"
 
 #, python-format
 msgid "Malformed endpoint URL (%(endpoint)s), see ERROR log for details."
 msgstr ""
-"ã\82¨ã\83³ã\83\89ã\83\9dã\82¤ã\83³ã\83\88 URL (%(endpoint)s) ã\81®å½¢å¼\8fã\81\8cæ­£ã\81\97ã\81\8fã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ã\80\82詳ã\81\97ã\81\8fã\81¯ã\82¨ã\83©ã\83¼ã\83»"
-"ã\83­ã\82°ã\82\92å\8f\82ç\85§ã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82"
+"ã\82¨ã\83³ã\83\89ã\83\9dã\82¤ã\83³ã\83\88 URL (%(endpoint)s) ã\81®å½¢å¼\8fã\81\8cæ­£ã\81\97ã\81\8fã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ã\80\82詳ã\81\97ã\81\8fã\81¯ã\82¨ã\83©ã\83¼ã\83­"
+"グを参照してください。"
 
 msgid "Marker could not be found"
 msgstr "マーカーが見つかりませんでした"
@@ -639,38 +651,39 @@ msgid "Method not callable: %s"
 msgstr "メソッドが呼び出し可能ではありません: %s"
 
 msgid "Missing entity ID from environment"
-msgstr "環境にエンティティー ID がありません"
+msgstr "環境情報にエンティティー ID が見つかりません"
 
 msgid ""
 "Modifying \"redelegation_count\" upon redelegation is forbidden. Omitting "
 "this parameter is advised."
 msgstr ""
-"å\86\8då§\94ä»»æ\99\82ã\81®ã\80\8credelegation_countã\80\8dã\81®å¤\89æ\9b´ã\81¯ç¦\81æ­¢ã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99ã\80\82ã\81\93ã\81®ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\83¼ã\82\92"
-"省略してください。"
+"å\86\8då§\94ä»»æ\99\82ã\81®ã\80\8credelegation_countã\80\8dã\81®å¤\89æ\9b´ã\81¯ç¦\81æ­¢ã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99ã\80\82ã\81\93ã\81®ã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\83¼ã\81¯"
+"指定しないでください。"
 
 msgid "Multiple domains are not supported"
 msgstr "複数のドメインはサポートされていません"
 
 msgid "Must be called within an active lock context."
-msgstr "ã\82¢ã\82¯ã\83\86ã\82£ã\83\96ã\83»ã\83­ã\83\83ã\82¯ã\83»コンテキスト内で呼び出されなければなりません。"
+msgstr "ã\82¢ã\82¯ã\83\86ã\82£ã\83\96ã\81ªã\83­ã\83\83ã\82¯コンテキスト内で呼び出されなければなりません。"
 
 msgid "Must specify either domain or project"
 msgstr "ドメインまたはプロジェクトのいずれかを指定する必要があります"
 
 msgid "Name field is required and cannot be empty"
-msgstr "ã\80\8cå\90\8då\89\8dã\80\8dã\83\95ã\82£ã\83¼ã\83«ã\83\89ã\81¯å¿\85é \88ã\83\95ã\82£ã\83¼ã\83«ã\83\89ã\81§ã\81\82ã\82\8bã\81\9fã\82\81、空にできません"
+msgstr "ã\80\8cå\90\8då\89\8dã\80\8dã\83\95ã\82£ã\83¼ã\83«ã\83\89ã\81¯å¿\85é \88ã\83\95ã\82£ã\83¼ã\83«ã\83\89ã\81§ã\81\82ã\82\8a、空にできません"
 
 msgid ""
 "No Authorization headers found, cannot proceed with OAuth related calls, if "
 "running under HTTPd or Apache, ensure WSGIPassAuthorization is set to On."
 msgstr ""
-"許å\8f¯ã\83\98ã\83\83ã\83\80ã\83¼ã\81\8cè¦\8bã\81¤ã\81\8bã\82\8aã\81¾ã\81\9bã\82\93ã\80\82OAuth é\96¢é\80£å\91¼ã\81³å\87ºã\81\97ã\82\92ç¶\9aè¡\8cã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82HTTPd ã\81¾ã\81\9f"
-"は Apache の下で実行している場合は、WSGIPassAuthorization が On に設定されて"
-"いることを確認してください。"
+"èª\8då\8f¯ã\81«ä½¿ç\94¨ã\81\99ã\82\8bã\83\98ã\83\83ã\83\80ã\83¼ã\81\8cè¦\8bã\81¤ã\81\8bã\82\89ã\81\9aã\80\81OAuth é\96¢é\80£ã\81®å\91¼ã\81³å\87ºã\81\97ã\82\92ç¶\9aè¡\8cã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82"
+"HTTPd または Apache の下で実行している場合は、WSGIPassAuthorization が On に"
+"設定されていることを確認してください。"
 
 msgid "No authenticated user"
 msgstr "認証されていないユーザー"
 
+#, fuzzy
 msgid ""
 "No encryption keys found; run keystone-manage fernet_setup to bootstrap one."
 msgstr ""
@@ -678,38 +691,38 @@ msgstr ""
 "を行ってください。"
 
 msgid "No options specified"
-msgstr "オプション指定なし"
+msgstr "オプションが指定されていません"
 
 #, python-format
 msgid "No policy is associated with endpoint %(endpoint_id)s."
 msgstr ""
 "エンドポイント %(endpoint_id)s に関連付けられているポリシーはありません。"
 
-#, python-format
+#, fuzzy, python-format
 msgid "No remaining uses for trust: %(trust_id)s"
-msgstr "トラストには使用が残っていません: %(trust_id)s"
+msgstr "トラスト %(trust_id)s には使用が残っていません"
 
 msgid "Non-default domain is not supported"
-msgstr "標準以外のドメインはサポートされません"
+msgstr "デフォルト以外のドメインはサポートされません"
 
 msgid "One of the trust agents is disabled or deleted"
-msgstr "ã\83\88ã\83©ã\82¹ã\83\88ã\83»ã\82¨ã\83¼ã\82¸ã\82§ã\83³ã\83\88ã\81® 1 ã\81¤ã\81\8cç\84¡å\8a¹å\8c\96ã\81¾ã\81\9fã\81¯削除されています"
+msgstr "ã\83\88ã\83©ã\82¹ã\83\88ã\82¨ã\83¼ã\82¸ã\82§ã\83³ã\83\88ã\81® 1 ã\81¤ã\81\8cç\84¡å\8a¹ã\81«ã\81ªã\81£ã\81¦ã\81\84ã\82\8bã\81\8b削除されています"
 
 #, python-format
 msgid ""
 "Option %(option)s found with no group specified while checking domain "
 "configuration request"
 msgstr ""
-"ドメイン構成要求の検査中にオプション %(option)s にグループが指定されていない"
-"ã\81\93ã\81¨ã\81\8cæ¤\9cå\87ºã\81\95ã\82\8cました"
+"ドメイン設定要求の検査中に、グループが指定されていないオプション %(option)s "
+"ã\81\8cè¦\8bã\81¤ã\81\8bã\82\8aました"
 
 #, python-format
 msgid ""
 "Option %(option)s in group %(group)s is not supported for domain specific "
 "configurations"
 msgstr ""
-"ドメイン固有の構成ではグループ %(group)s 内のオプション %(option)s はサポート"
-"ã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\9bã\82\93"
+"ドメイン固有の設定ではグループ %(group)s のオプション %(option)s はサポートさ"
+"れていません"
 
 #, python-format
 msgid "Project (%s)"
@@ -717,7 +730,7 @@ msgstr "プロジェクト (%s)"
 
 #, python-format
 msgid "Project is disabled: %s"
-msgstr "プロジェクトが無効化されています: %s"
+msgstr "プロジェクト %s が無効になっています"
 
 msgid "Redelegation allowed for delegated by trust only"
 msgstr "再委任はトラストによる委任にのみ許可されます"
@@ -731,7 +744,7 @@ msgstr ""
 "%(max_count)d] を超えています"
 
 msgid "Request Token does not have an authorizing user id"
-msgstr "要求トークンに許可ユーザー ID が含まれていません"
+msgstr "è¦\81æ±\82ã\81\95ã\82\8cã\81\9fã\83\88ã\83¼ã\82¯ã\83³ã\81«è¨±å\8f¯ã\83¦ã\83¼ã\82¶ã\83¼ ID ã\81\8cå\90«ã\81¾ã\82\8cã\81¦ã\81\84ã\81¾ã\81\9bã\82\93"
 
 #, python-format
 msgid ""
@@ -739,10 +752,11 @@ msgid ""
 "server could not comply with the request because the attribute size is "
 "invalid (too large). The client is assumed to be in error."
 msgstr ""
-"要求属性 %(attribute)s は %(size)i 以下でなければなりません。属性のサイズが無"
-"効である (大きすぎる) ため、サーバーは要求に従うことができませんでした。クラ"
-"ã\82¤ã\82¢ã\83³ã\83\88ã\81§ã\82¨ã\83©ã\83¼ã\81\8cç\99ºç\94\9fã\81\97ã\81¦ã\81\84ã\82\8bã\81¨è¦\8bã\81ªã\81\95れます。"
+"要求された属性 %(attribute)s のサイズは %(size)i 以下でなければなりません。属"
+"性のサイズが無効である (大きすぎる) ため、サーバーは要求に応じることができま"
+"ã\81\9bã\82\93ã\81§ã\81\97ã\81\9fã\80\82ã\82¯ã\83©ã\82¤ã\82¢ã\83³ã\83\88ã\81§ã\82¨ã\83©ã\83¼ã\81\8cç\99ºç\94\9fã\81\97ã\81¦ã\81\84ã\82\8bã\81¨è\80\83ã\81\88ã\82\89れます。"
 
+#, fuzzy
 msgid "Request must have an origin query parameter"
 msgstr "要求には起点照会パラメーターが必要です"
 
@@ -750,7 +764,7 @@ msgid "Request token is expired"
 msgstr "要求トークンの有効期限が切れています"
 
 msgid "Request token not found"
-msgstr "要求トークンが見つかりません"
+msgstr "è¦\81æ±\82ã\81\95ã\82\8cã\81\9fã\83\88ã\83¼ã\82¯ã\83³ã\81\8cè¦\8bã\81¤ã\81\8bã\82\8aã\81¾ã\81\9bã\82\93"
 
 msgid "Requested expiration time is more than redelegated trust can provide"
 msgstr "要求された有効期限は再委任されたトラストが提供可能な期間を超えています"
@@ -760,8 +774,8 @@ msgid ""
 "Requested redelegation depth of %(requested_count)d is greater than allowed "
 "%(max_count)d"
 msgstr ""
-"%(requested_count)d の要求された再委任の深さが、許可された %(max_count)d を超"
-"えています"
+"要求された再委任の深さ %(requested_count)d が、許可された上限 %(max_count)d "
+"ã\82\92è¶\85ã\81\88ã\81¦ã\81\84ã\81¾ã\81\99"
 
 #, python-format
 msgid "Role %s not found"
@@ -774,23 +788,23 @@ msgid ""
 msgstr ""
 "eventlet を介した keystone の実行は Kilo 以降では推奨されておらず、WSGI サー"
 "バー (mod_wsgi など) での実行が推奨されています。eventlet 下での keystone の"
-"サポートは「M」-リリースで削除される予定です。"
+"サポートは「M」リリースで削除される予定です。"
 
 msgid "Scoping to both domain and project is not allowed"
-msgstr "ã\83\89ã\83¡ã\82¤ã\83³ã\81¨ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88ã\81®ä¸¡æ\96¹ã\82\92ã\82¹ã\82³ã\83¼ã\83\97ã\81¨ã\81\99ã\82\8bã\81\93ã\81¨ã\81¯è¨±å\8f¯ã\81\95ã\82\8cません"
+msgstr "ã\83\89ã\83¡ã\82¤ã\83³ã\81¨ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88ã\81®ä¸¡æ\96¹ã\81«ã\82¹ã\82³ã\83¼ã\83\97ã\82\92設å®\9aã\81\99ã\82\8bã\81\93ã\81¨ã\81¯ã\81§ã\81\8dません"
 
 msgid "Scoping to both domain and trust is not allowed"
-msgstr "ã\83\89ã\83¡ã\82¤ã\83³ã\81¨ã\83\88ã\83©ã\82¹ã\83\88ã\81®ä¸¡æ\96¹ã\82\92ã\82¹ã\82³ã\83¼ã\83\97ã\81¨ã\81\99ã\82\8bã\81\93ã\81¨ã\81¯è¨±å\8f¯ã\81\95ã\82\8cません"
+msgstr "ã\83\89ã\83¡ã\82¤ã\83³ã\81¨ã\83\88ã\83©ã\82¹ã\83\88ã\81®ä¸¡æ\96¹ã\81«ã\82¹ã\82³ã\83¼ã\83\97ã\82\92設å®\9aã\81\99ã\82\8bã\81\93ã\81¨ã\81¯ã\81§ã\81\8dません"
 
 msgid "Scoping to both project and trust is not allowed"
-msgstr "ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88ã\81¨ã\83\88ã\83©ã\82¹ã\83\88ã\81®ä¸¡æ\96¹ã\82\92ã\82¹ã\82³ã\83¼ã\83\97ã\81¨ã\81\99ã\82\8bã\81\93ã\81¨ã\81¯è¨±å\8f¯ã\81\95ã\82\8cません"
+msgstr "ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88ã\81¨ã\83\88ã\83©ã\82¹ã\83\88ã\81®ä¸¡æ\96¹ã\81«ã\82¹ã\82³ã\83¼ã\83\97ã\82\92設å®\9aã\81\99ã\82\8bã\81\93ã\81¨ã\81¯ã\81§ã\81\8dません"
 
 #, python-format
 msgid "Service Provider %(sp)s is disabled"
-msgstr "ã\82µã\83¼ã\83\93ã\82¹ã\83»ã\83\97ã\83­ã\83\90ã\82¤ã\83\80ã\83¼ %(sp)s ã\81¯ç\84¡å\8a¹ã\81«ã\81ªã\81£ã\81¦ã\81\84ã\81¾ã\81\99"
+msgstr "サービスプロバイダー %(sp)s は無効になっています"
 
 msgid "Some of requested roles are not in redelegated trust"
-msgstr "要求された役割の一部が再委任されたトラスト内にありません"
+msgstr "要求されたロールの一部が再委任されたトラスト内にありません"
 
 msgid "Specify a domain or project, not both"
 msgstr "ドメインかプロジェクトを指定してください。両方は指定しないでください"
@@ -809,27 +823,28 @@ msgid ""
 "String length exceeded.The length of string '%(string)s' exceeded the limit "
 "of column %(type)s(CHAR(%(length)d))."
 msgstr ""
-"ストリングの長さを超えました。ストリング %(string)s' の長さが列 "
-"%(type)s(CHAR(%(length)d)) の制限を超えました。"
+"文字列が長過ぎます。文字列 %(string)s' の長さが列 %(type)s(CHAR(%(length)d)) "
+"の制限を超えました。"
 
 msgid "The --all option cannot be used with the --domain-name option"
 msgstr "--all オプションを --domain-name オプションと併用することはできません"
 
 #, python-format
 msgid "The Keystone configuration file %(config_file)s could not be found."
-msgstr "Keystone 構成ファイル %(config_file)s が見つかりませんでした。"
+msgstr "Keystone 設定ファイル %(config_file)s が見つかりませんでした。"
 
 #, python-format
 msgid ""
 "The Keystone domain-specific configuration has specified more than one SQL "
 "driver (only one is permitted): %(source)s."
 msgstr ""
-"keystone ドメイン固有構成で複数の SQL ドライバーが指定されています (1 つのみ"
-"許可): %(source)s。"
+"keystone ドメイン固有設定で複数の SQL ドライバーが指定されています (1 つしか"
+"指定できません): %(source)s。"
 
 msgid "The action you have requested has not been implemented."
 msgstr "要求したアクションは実装されていません。"
 
+#, fuzzy
 msgid "The authenticated user should match the trustor."
 msgstr "認証ユーザーは委託者と一致している必要があります。"
 
@@ -838,8 +853,8 @@ msgid ""
 "server does not use PKI tokens otherwise this is the result of "
 "misconfiguration."
 msgstr ""
-"è¦\81æ±\82ã\81\95ã\82\8cã\81\9f証æ\98\8eæ\9b¸ã\81\8cã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ã\80\82ã\81\93ã\81®ã\82µã\83¼ã\83\90ã\83¼ã\81§ã\81¯ PKI ã\83\88ã\83¼ã\82¯ã\83³ã\81\8c使ç\94¨ã\81\95ã\82\8cã\81ªã\81\84ã\81\8bã\80\81"
-"ã\81¾ã\81\9fã\81¯çµ\90æ\9e\9cç\9a\84ã\81«æ§\8bæ\88\90ã\81\8cæ­£ã\81\97ã\81\8fã\81ªã\81\84ã\81\93ã\81¨ã\81\8c考えられます。 "
+"è¦\81æ±\82ã\81\95ã\82\8cã\81\9f証æ\98\8eæ\9b¸ã\81\8cã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ã\80\82ã\81\93ã\81®ã\82µã\83¼ã\83\90ã\83¼ã\81§ã\81¯ PKI ã\83\88ã\83¼ã\82¯ã\83³ã\81\8c使ç\94¨ã\81\95ã\82\8cã\81¦ã\81\84ã\81ªã\81\84"
+"ã\81\8bã\80\81ã\81\9dã\81\86ã\81§ã\81ªã\81\84å ´å\90\88ã\81¯è¨­å®\9aã\81\8cé\96\93é\81\95ã\81£ã\81¦ã\81\84ã\82\8bã\81¨考えられます。 "
 
 #, python-format
 msgid ""
@@ -847,7 +862,7 @@ msgid ""
 "not comply with the request because the password is invalid."
 msgstr ""
 "パスワードの長さは %(size)i 以下でなければなりません。パスワードが無効である"
-"ã\81\9fã\82\81ã\80\81ã\82µã\83¼ã\83\90ã\83¼ã\81¯è¦\81æ±\82ã\81«å¾\93ã\81\86ことができませんでした。"
+"ã\81\9fã\82\81ã\80\81ã\82µã\83¼ã\83\90ã\83¼ã\81¯è¦\81æ±\82ã\81«å¿\9cã\81\98ã\82\8bことができませんでした。"
 
 msgid "The request you have made requires authentication."
 msgstr "実行された要求には認証が必要です。"
@@ -869,38 +884,40 @@ msgstr "要求したサービスは現在このサーバーでは使用できま
 msgid ""
 "The specified parent region %(parent_region_id)s would create a circular "
 "region hierarchy."
-msgstr "指定された親領域 %(parent_region_id)s は循環領域階層を作成します。"
+msgstr ""
+"指定された親リージョン %(parent_region_id)s では、リージョン階層構造でループ"
+"が発生してしまいます。"
 
 #, python-format
 msgid ""
 "The value of group %(group)s specified in the config should be a dictionary "
 "of options"
 msgstr ""
-"構成で指定されたグループ %(group)s の値はオプションのディクショナリーにする必"
-"要があります"
+"設定で指定されたグループ %(group)s の値はオプションの辞書にする必要があります"
 
 msgid "There should not be any non-oauth parameters"
-msgstr "非 oauth パラメーターが存在していてはなりません"
+msgstr "oauth 関連以外のパラメーターが含まれていてはいけません"
 
-#, python-format
+#, fuzzy, python-format
 msgid "This is not a recognized Fernet payload version: %s"
-msgstr "ã\81\93ã\82\8cã\81¯èª\8dè­\98ã\81\95ã\82\8cã\81\9f Fernet ã\83\9aã\82¤ã\83­ã\83¼ã\83\89ã\83»ã\83\90ã\83¼ã\82¸ã\83§ã\83³ã\81§ã\81¯ã\81\82ã\82\8aã\81¾ã\81\9bã\82\93: %s"
+msgstr "これは認識された Fernet ペイロードバージョンではありません: %s"
 
+#, fuzzy
 msgid ""
 "This is not a v2.0 Fernet token. Use v3 for trust, domain, or federated "
 "tokens."
 msgstr ""
-"ã\81\93ã\82\8cã\81¯ v2.0 Fernet ã\83\88ã\83¼ã\82¯ã\83³ã\81§ã\81¯ã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ã\80\82ã\83\88ã\83©ã\82¹ã\83\88ã\83»ã\83\88ã\83¼ã\82¯ã\83³ã\80\81ã\83\89ã\83¡ã\82¤ã\83³ã\83»ã\83\88ã\83¼"
-"ã\82¯ã\83³ã\80\81ã\81¾ã\81\9fã\81¯çµ±å\90\88ã\83\88ã\83¼ã\82¯ã\83³ã\81«ã\81¯ v3 ã\82\92使ç\94¨ã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82"
+"ã\81\93ã\82\8cã\81¯ v2.0 Fernet ã\83\88ã\83¼ã\82¯ã\83³ã\81§ã\81¯ã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ã\80\82ã\83\88ã\83©ã\82¹ã\83\88ã\83\88ã\83¼ã\82¯ã\83³ã\80\81ã\83\89ã\83¡ã\82¤ã\83³ã\83\88ã\83¼ã\82¯"
+"ン、または統合トークンには v3 を使用してください。"
 
 msgid ""
 "Timestamp not in expected format. 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 ""
-"ã\82¿ã\82¤ã\83 ã\83»ã\82¹ã\82¿ã\83³ã\83\97ã\81\8cã\80\81äº\88æ\9c\9fã\81\95ã\82\8cã\81\9få½¢å¼\8fã\81«ã\81ªã\81£ã\81¦ã\81\84ã\81¾ã\81\9bã\82\93ã\80\82è¦\81æ±\82ã\81®å½¢å¼\8fã\81\8c誤ã\81£ã\81¦ã\81\84ã\82\8b"
-"ã\81\8bã\80\81ã\81¾ã\81\9fã\81¯è¦\81æ±\82ã\81\8cæ­£ã\81\97ã\81\8fã\81ªã\81\84ã\81\9fã\82\81ã\80\81ã\82µã\83¼ã\83\90ã\83¼ã\81¯è¦\81æ±\82ã\81«å¿\9cã\81\98ã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\81§ã\81\97"
-"ã\81\9fã\80\82ã\82¯ã\83©ã\82¤ã\82¢ã\83³ã\83\88ã\81¯ã\82¨ã\83©ã\83¼ã\81«ã\81ªã\81£ã\81¦ã\81\84ã\82\8bã\81¨ã\81¿ã\81ªã\81\95れます。"
+"ã\82¿ã\82¤ã\83 ã\82¹ã\82¿ã\83³ã\83\97ã\81\8cæ\83³å®\9aã\81\95ã\82\8cã\81\9få½¢å¼\8fã\81«ã\81ªã\81£ã\81¦ã\81\84ã\81¾ã\81\9bã\82\93ã\80\82è¦\81æ±\82ã\81®å½¢å¼\8fã\81\8cä¸\8dæ­£ã\82\82ã\81\97ã\81\8fã\81¯æ­£ã\81\97"
+"ã\81\8fã\81ªã\81\84ã\81\9fã\82\81ã\80\81ã\82µã\83¼ã\83\90ã\83¼ã\81¯è¦\81æ±\82ã\81«å¿\9cã\81\98ã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\81§ã\81\97ã\81\9fã\80\82ã\82¯ã\83©ã\82¤ã\82¢ã\83³ã\83\88ã\81§ã\82¨"
+"ã\83©ã\83¼ã\81\8cç\99ºç\94\9fã\81\97ã\81¦ã\81\84ã\82\8bã\81¨è\80\83ã\81\88ã\82\89れます。"
 
 #, python-format
 msgid ""
@@ -908,8 +925,8 @@ msgid ""
 "the specific domain, i.e.: keystone-manage domain_config_upload --domain-"
 "name %s"
 msgstr ""
-"このエラーに関する詳細を得るには、次のように、特定ドメインに対してこのコマン"
-"ã\83\89ã\82\92å\86\8då®\9fè¡\8cã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84: keystone-manage domain_config_upload --domain-name %s"
+"このエラーに関する詳細を得るには、特定ドメインに対してこのコマンドを再実行し"
+"てください: keystone-manage domain_config_upload --domain-name %s"
 
 msgid "Token belongs to another user"
 msgstr "トークンが別のユーザーに属しています"
@@ -917,9 +934,11 @@ msgstr "トークンが別のユーザーに属しています"
 msgid "Token does not belong to specified tenant."
 msgstr "トークンが指定されたテナントに所属していません。"
 
+#, fuzzy
 msgid "Trustee has no delegated roles."
-msgstr "受託者に委任された役割がありません。"
+msgstr "受託者に委任されたロールがありません。"
 
+#, fuzzy
 msgid "Trustor is disabled."
 msgstr "委託者は無効です。"
 
@@ -928,50 +947,51 @@ msgid ""
 "Trying to update group %(group)s, so that, and only that, group must be "
 "specified in the config"
 msgstr ""
-"ã\82°ã\83«ã\83¼ã\83\97 %(group)s ã\82\92æ\9b´æ\96°ã\81\97ã\82\88ã\81\86ã\81¨ã\81\97ã\81¦ã\81\84ã\82\8bã\81\9fã\82\81ã\80\81ã\81\9dã\81®ã\82ªã\83\97ã\82·ã\83§ã\83³ã\81®ã\81¿ã\82\92æ§\8bæ\88\90ã\81§æ\8c\87å®\9a"
-"する必要があります"
+"ã\82°ã\83«ã\83¼ã\83\97 %(group)s ã\82\92æ\9b´æ\96°ã\81\97ã\82\88ã\81\86ã\81¨ã\81\97ã\81¦ã\81\84ã\81¾ã\81\99ã\81\8cã\80\81ã\81\9dã\81®å ´å\90\88ã\81¯è¨­å®\9aã\81§ã\82°ã\83«ã\83¼ã\83\97ã\81®ã\81¿ã\82\92"
+"指定する必要があります"
 
 #, python-format
 msgid ""
 "Trying to update option %(option)s in group %(group)s, but config provided "
 "contains option %(option_other)s instead"
 msgstr ""
-"グループ %(group)s 内のオプション %(option)s を更新しようとしていますが、指定"
-"ã\81\95ã\82\8cã\81\9fæ§\8bæ\88\90には代わりにオプション %(option_other)s が含まれています"
+"グループ %(group)s のオプション %(option)s を更新しようとしましたが、指定され"
+"ã\81\9f設å®\9aには代わりにオプション %(option_other)s が含まれています"
 
 #, python-format
 msgid ""
 "Trying to update option %(option)s in group %(group)s, so that, and only "
 "that, option must be specified  in the config"
 msgstr ""
-"グループ %(group)s 内のオプション %(option)s を更新しようとしているため、その"
-"オプションのみを構成で指定する必要があります"
+"グループ %(group)s のオプション %(option)s を更新しようとしていますが、その場"
+"合は設定でオプションのみを指定する必要があります"
 
 msgid ""
 "Unable to access the keystone database, please check it is configured "
 "correctly."
 msgstr ""
-"keystone データベースにアクセスできません。このデータベースが正しく構成されて"
+"keystone データベースにアクセスできません。このデータベースが正しく設定されて"
 "いるかどうかを確認してください。"
 
-#, python-format
+#, fuzzy, python-format
 msgid "Unable to consume trust %(trust_id)s, unable to acquire lock."
-msgstr "トラスト %(trust_id)s を使用できず、ロックを取得できません。"
+msgstr "トラスト %(trust_id)s を消費できず、ロックを取得できません。"
 
 #, python-format
 msgid ""
 "Unable to delete region %(region_id)s because it or its child regions have "
 "associated endpoints."
 msgstr ""
-"領域 %(region_id)s またはその子領域にエンドポイントが関連付けられているため、"
-"ã\81\93ã\81®é \98å\9f\9fを削除できません。"
+"リージョン %(region_id)s またはその子リージョンがエンドポイントに関連付けられ"
+"ã\81¦ã\81\84ã\82\8bã\81\9fã\82\81ã\80\81ã\81\93ã\81®ã\83ªã\83¼ã\82¸ã\83§ã\83³を削除できません。"
 
 #, python-format
 msgid "Unable to find valid groups while using mapping %(mapping_id)s"
 msgstr ""
-"マッピング %(mapping_id)s の使用中に有効なグループが見つかりませんでした"
+"マッピング %(mapping_id)s を使用する際に、有効なグループが見つかりませんでし"
+"た"
 
-#, python-format
+#, fuzzy, python-format
 msgid ""
 "Unable to get a connection from pool id %(id)s after %(seconds)s seconds."
 msgstr ""
@@ -979,13 +999,13 @@ msgstr ""
 
 #, python-format
 msgid "Unable to locate domain config directory: %s"
-msgstr "ドメイン構成ディレクトリーが見つかりません: %s"
+msgstr "ドメイン設定ディレクトリーが見つかりません: %s"
 
 #, python-format
 msgid "Unable to lookup user %s"
 msgstr "ユーザー %s を検索できません"
 
-#, python-format
+#, fuzzy, python-format
 msgid ""
 "Unable to reconcile identity attribute %(attribute)s as it has conflicting "
 "values %(new)s and %(old)s"
@@ -1000,12 +1020,12 @@ msgid ""
 "%(reason)s"
 msgstr ""
 "SAML アサーションに署名できません。このサーバーに xmlsec1 がインストールされ"
-"ã\81¦ã\81\84ã\81ªã\81\84ã\81\8bã\80\81誤ã\81£ã\81\9fæ§\8bæ\88\90ã\81«ã\82\88ã\82\8bçµ\90æ\9e\9cと考えられます。理由: %(reason)s"
+"ã\81¦ã\81\84ã\81ªã\81\84ã\81\8bã\80\81設å®\9aã\81\8c誤ã\81£ã\81¦ã\81\84ã\82\8bã\81\9fã\82\81と考えられます。理由: %(reason)s"
 
 msgid "Unable to sign token."
 msgstr "トークンに署名できません。"
 
-#, python-format
+#, fuzzy, python-format
 msgid "Unexpected assignment type encountered, %s"
 msgstr "無効な割り当てタイプ %s が検出されました"
 
@@ -1014,10 +1034,10 @@ msgid ""
 "Unexpected combination of grant attributes - User: %(user_id)s, Group: "
 "%(group_id)s, Project: %(project_id)s, Domain: %(domain_id)s"
 msgstr ""
-"認可属性 (ユーザー: %(user_id)s、グループ: %(group_id)s、プロジェクト: "
-"%(project_id)s、ドメイン: %(domain_id)s) の組み合わせが正しくありません。"
+"認可属性 の組み合わせ (ユーザー: %(user_id)s、グループ: %(group_id)s、プロ"
+"ジェクト: %(project_id)s、ドメイン: %(domain_id)s) が正しくありません。"
 
-#, python-format
+#, fuzzy, python-format
 msgid "Unexpected status requested for JSON Home response, %s"
 msgstr "JSON ホーム応答に対して予期しない状況が要求されました。%s"
 
@@ -1026,23 +1046,23 @@ msgstr "不明なターゲット"
 
 #, python-format
 msgid "Unknown domain '%(name)s' specified by --domain-name"
-msgstr "ä¸\8dæ\98\8eã\81ªã\83\89ã\83¡ã\82¤ã\83³ '%(name)s' ã\81\8c --domain-name ã\81«ã\82\88ã\81£ã\81¦指定されました"
+msgstr "ä¸\8dæ\98\8eã\81ªã\83\89ã\83¡ã\82¤ã\83³ '%(name)s' ã\81\8c --domain-name ã\81§指定されました"
 
 #, python-format
 msgid "Unknown token version %s"
-msgstr "ã\83\88ã\83¼ã\82¯ã\83³ã\83»ã\83\90ã\83¼ã\82¸ã\83§ã\83³ %s ã\81¯ä¸\8dæ\98\8eã\81§ã\81\99"
+msgstr "トークンバージョン %s は不明です"
 
 #, python-format
 msgid "Unregistered dependency: %(name)s for %(targets)s"
-msgstr "æ\9cªç\99»é\8c²ã\81®ä¾\9då­\98é\96¢ä¿\82: %(targets)s ã\81® %(name)s"
+msgstr "æ\9cªç\99»é\8c²ã\81®ä¾\9då­\98é\96¢ä¿\82: %(targets)s ã\81«å¯¾ã\81\99ã\82\8b %(name)s"
 
 msgid "Update of `parent_id` is not allowed."
-msgstr "「parent_id」の更新は許可されていません。"
+msgstr "\"parent_id\" の更新は許可されていません。"
 
 msgid "Use a project scoped token when attempting to create a SAML assertion"
 msgstr ""
-"SAML ã\82¢ã\82µã\83¼ã\82·ã\83§ã\83³ã\81®ä½\9cæ\88\90ã\82\92試ã\81¿ã\82\8bã\81¨ã\81\8dã\81¯ã\80\81ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88ç¯\84å\9b²ã\83\88ã\83¼ã\82¯ã\83³ã\82\92使ç\94¨ã\81\97ã\81¦ã\81\8fã\81 "
-"ã\81\95ã\81\84ã\80\82"
+"SAML ã\82¢ã\82µã\83¼ã\82·ã\83§ã\83³ã\81®ä½\9cæ\88\90ã\82\92è¡\8cã\81\86ã\81¨ã\81\8dã\81¯ã\80\81ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88ã\81«ã\82¹ã\82³ã\83¼ã\83\97ã\81\8c設å®\9aã\81\95ã\82\8cã\81\9fã\83\88ã\83¼ã\82¯"
+"ã\83³ã\82\92使ç\94¨ã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84"
 
 #, python-format
 msgid "User %(u_id)s is unauthorized for tenant %(t_id)s"
@@ -1051,19 +1071,19 @@ msgstr "ユーザー %(u_id)s はテナント %(t_id)s のアクセス権限が
 #, python-format
 msgid "User %(user_id)s already has role %(role_id)s in tenant %(tenant_id)s"
 msgstr ""
-"ユーザー %(user_id)s には既に役割 %(role_id)s がテナント %(tenant_id)s にあり"
-"ます"
+"ユーザー %(user_id)s にはすでにテナント %(tenant_id)s でロール %(role_id)s が"
+"割り当てられています。"
 
 #, python-format
 msgid "User %(user_id)s has no access to domain %(domain_id)s"
 msgstr ""
-"ã\83¦ã\83¼ã\82¶ã\83¼ %(user_id)s ã\81«ã\81¯ã\83\89ã\83¡ã\82¤ã\83³ %(domain_id)s ã\81¸ã\81®ã\82¢ã\82¯ã\82»ã\82¹æ¨©é\99\90ã\81\8cã\81\82ã\82\8aã\81¾ã\81\9bã\82\93"
+"ユーザー %(user_id)s はドメイン %(domain_id)s へのアクセス権限がありません"
 
 #, python-format
 msgid "User %(user_id)s has no access to project %(project_id)s"
 msgstr ""
-"ã\83¦ã\83¼ã\82¶ã\83¼ %(user_id)s ã\81«ã\81¯ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88 %(project_id)s ã\81¸ã\81®ã\82¢ã\82¯ã\82»ã\82¹æ¨©é\99\90ã\81\8cã\81\82ã\82\8aã\81¾"
-"ã\81\9bã\82\93"
+"ã\83¦ã\83¼ã\82¶ã\83¼ %(user_id)s ã\81¯ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88 %(project_id)s ã\81¸ã\81®ã\82¢ã\82¯ã\82»ã\82¹æ¨©é\99\90ã\81\8cã\81\82ã\82\8aã\81¾ã\81\9b"
+"ん"
 
 #, python-format
 msgid "User %(user_id)s is already a member of group %(group_id)s"
@@ -1078,20 +1098,21 @@ msgstr "ユーザー ID が一致しません"
 
 #, python-format
 msgid "User is disabled: %s"
-msgstr "ユーザーが無効化されています: %s"
+msgstr "ユーザーが無効になっています: %s"
 
 msgid "User is not a member of the requested project"
 msgstr "ユーザーは、要求されたプロジェクトのメンバーではありません"
 
+#, fuzzy
 msgid "User is not a trustee."
 msgstr "ユーザーは受託者ではありません。"
 
 msgid "User not found"
-msgstr "ユーザーが見つかりませんでした"
+msgstr "ユーザーが見つかりません"
 
-#, python-format
+#, fuzzy, python-format
 msgid "User type %s not supported"
-msgstr "ユーザー・タイプ %s はサポートされていません"
+msgstr "ユーザー %s はサポートされていません"
 
 msgid "You are not authorized to perform the requested action."
 msgstr "要求されたアクションを実行する許可がありません。"
@@ -1109,30 +1130,34 @@ msgstr "`key_mangler` オプションは関数参照でなければなりませ
 msgid "any options"
 msgstr "任意のオプション"
 
+#, fuzzy
 msgid "auth_type is not Negotiate"
 msgstr "auth_type は折衝されていません"
 
 msgid "authorizing user does not have role required"
-msgstr "許可を与えるユーザーに、必要な役割がありません"
+msgstr "ユーザーを認可するのに必要なロールがありません"
 
+#, fuzzy
 msgid "cache_collection name is required"
 msgstr "cache_collection name は必須です"
 
 #, python-format
 msgid "cannot create a project in a branch containing a disabled project: %s"
 msgstr ""
-"無効なプロジェクトを含むブランチにプロジェクトを作成することはできません: %s"
+"無効になっているプロジェクトを含むブランチにプロジェクトを作成することはでき"
+"ません: %s"
 
 msgid "cannot create a project within a different domain than its parents."
-msgstr "親とは別のドメイン内にプロジェクトを作成することはできません。"
+msgstr "プロジェクトは親とは別のドメイン内には作成できません。"
 
 msgid "cannot delete a domain that is enabled, please disable it first."
 msgstr ""
-"有効なドメインは削除できません。最初に有効なドメインを無効にしてください。"
+"有効になっているドメインは削除できません。最初にそのドメインを無効にしてくだ"
+"さい。"
 
 #, python-format
 msgid "cannot delete the project %s since it is not a leaf in the hierarchy."
-msgstr "プロジェクト %s は階層内のリーフではないため、削除できません。"
+msgstr "プロジェクト %s は階層内の末端ではないため、削除できません。"
 
 #, python-format
 msgid "cannot disable project %s since its subtree contains enabled projects"
@@ -1142,8 +1167,9 @@ msgstr ""
 
 #, python-format
 msgid "cannot enable project %s since it has disabled parents"
-msgstr "プロジェクト %s は無効になっている親を含むため、有効にできません"
+msgstr "親が無効になっているプロジェクト %s は有効にできません"
 
+#, fuzzy
 msgid "database db_name is required"
 msgstr "database db_name は必須です"
 
@@ -1151,7 +1177,7 @@ msgid "db_hosts value is required"
 msgstr "db_hosts 値は必須です"
 
 msgid "delete the default domain"
-msgstr "ã\83\87ã\83\95ã\82©ã\83«ã\83\88ã\83»ã\83\89ã\83¡ã\82¤ã\83³ã\82\92å\89\8aé\99¤ã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84"
+msgstr "デフォルトドメインを削除してください"
 
 #, python-format
 msgid "group %(group)s"
@@ -1161,8 +1187,8 @@ msgid ""
 "idp_contact_type must be one of: [technical, other, support, administrative "
 "or billing."
 msgstr ""
-"idp_contact_type は technical、other、support、administrative、または "
-"billing のいずれかでなければなりません。"
+"idp_contact_type は technical、other、support、administrative、billing のいず"
+"れかでなければなりません。"
 
 msgid "integer value expected for mongo_ttl_seconds"
 msgstr "mongo_ttl_seconds には整数値が必要です"
@@ -1183,23 +1209,28 @@ msgstr "使用可能な SSL サポートがありません"
 
 #, python-format
 msgid "option %(option)s in group %(group)s"
-msgstr "グループ %(group)s のオプション %(option)s"
+msgstr "グループ %(group)s のオプション %(option)s"
 
+#, fuzzy
 msgid "pad must be single character"
 msgstr "埋め込みは単一文字でなければなりません"
 
+#, fuzzy
 msgid "padded base64url text must be multiple of 4 characters"
 msgstr "埋め込まれた base64url テキストは 4 の倍数の文字数でなければなりません"
 
 msgid "provided consumer key does not match stored consumer key"
-msgstr "指定されたコンシューマー鍵は保管済みコンシューマー鍵と一致しません"
+msgstr ""
+"指定されたコンシューマー鍵は保存されているコンシューマー鍵と一致しません"
 
 msgid "provided request key does not match stored request key"
-msgstr "指定された要求鍵は保管済み要求鍵と一致しません"
+msgstr "指定された要求鍵は保管されている要求鍵と一致しません"
 
+#, fuzzy
 msgid "provided verifier does not match stored verifier"
-msgstr "指定されたベリファイヤーは保管済みベリファイヤーと一致しません"
+msgstr "指定されたベリファイヤーは保存されているベリファイヤーと一致しません"
 
+#, fuzzy
 msgid "region not type dogpile.cache.CacheRegion"
 msgstr "領域のタイプが dogpile.cache.CacheRegion ではありません"
 
@@ -1210,45 +1241,43 @@ msgid "remaining_uses must not be set if redelegation is allowed"
 msgstr "再委任が許可されている場合は remaining_uses を設定してはなりません"
 
 msgid "replicaset_name required when use_replica is True"
-msgstr "use_replica が TRUE の場合は replicaset_name が必要です"
+msgstr "use_replica が True の場合は replicaset_name が必要です"
 
 #, python-format
 msgid ""
 "request to update group %(group)s, but config provided contains group "
 "%(group_other)s instead"
 msgstr ""
-"グループ %(group)s の更新を要求しましたが、指定された構成には代わりにグルー"
+"グループ %(group)s の更新を要求しましたが、指定された設定には代わりにグルー"
 "プ %(group_other)s が含まれています"
 
 msgid "rescope a scoped token"
-msgstr "スコープ宣言されたトークンを再スコープ宣言します"
+msgstr "スコープが設定されたトークンのスコープを設定し直します"
 
-#, python-format
+#, fuzzy, python-format
 msgid "text is multiple of 4, but pad \"%s\" occurs before 2nd to last char"
 msgstr ""
 "テキストは 4 の倍数ですが、最後から2 つ目の文字の前に埋め込み \"%s\" あります"
 
-#, python-format
+#, fuzzy, python-format
 msgid "text is multiple of 4, but pad \"%s\" occurs before non-pad last char"
 msgstr ""
 "テキストは 4 の倍数ですが、埋め込みではない最後の文字の前に埋め込み \"%s\" あ"
 "ります"
 
-#, python-format
+#, fuzzy, python-format
 msgid "text is not a multiple of 4, but contains pad \"%s\""
 msgstr "テキストは 4 の倍数ではありませんが、埋め込み \"%s\" が含まれています"
 
 #, python-format
 msgid "tls_cacertdir %s not found or is not a directory"
 msgstr ""
-"tls_cacertdir %s ã\81\8cè¦\8bã\81¤ã\81\8bã\82\8aã\81¾ã\81\9bã\82\93ã\81§ã\81\97ã\81\9fã\80\82ã\81¾ã\81\9fは、ディレクトリではありません。"
+"tls_cacertdir %s ã\81\8cè¦\8bã\81¤ã\81\8bã\82\89ã\81ªã\81\84ã\80\81ã\82\82ã\81\97ã\81\8fは、ディレクトリではありません。"
 
 #, python-format
 msgid "tls_cacertfile %s not found or is not a file"
-msgstr ""
-"tls_cacertfile %s が見つかりませんでした。または、ファイルではありません。"
+msgstr "tls_cacertfile %s が見つからない、もしくは、ファイルではありません。"
 
 #, python-format
 msgid "token reference must be a KeystoneToken type, got: %s"
-msgstr ""
-"トークン参照は KeystoneToken タイプである必要があります。%s を受け取りました"
+msgstr "トークン参照は KeystoneToken 型である必要があります。%s を受信しました"
index c591d79..3beb3a2 100644 (file)
@@ -6,16 +6,16 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 9.0.0.dev14\n"
+"Project-Id-Version: keystone 8.0.0.0rc2.dev1\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-24 06:09+0000\n"
+"POT-Creation-Date: 2015-10-01 06:09+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 2.0\n"
+"Generated-By: Babel 2.1.1\n"
 
 #: keystone/exception.py:48
 msgid "missing exception kwargs (programmer error)"
index 64eab4e..ce32fa8 100644 (file)
@@ -6,16 +6,16 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 9.0.0.dev14\n"
+"Project-Id-Version: keystone 8.0.0.0rc2.dev1\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-24 06:09+0000\n"
+"POT-Creation-Date: 2015-10-01 06:09+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 2.0\n"
+"Generated-By: Babel 2.1.1\n"
 
 #: keystone/exception.py:78
 #, python-format
index ae6dc84..d773915 100644 (file)
@@ -6,19 +6,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 8.0.0.0b4.dev56\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-21 06:08+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2014-08-31 03:19+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Korean (Korea) (http://www.transifex.com/openstack/keystone/"
-"language/ko_KR/)\n"
+"Language-Team: Korean (South Korea)\n"
 "Language: ko-KR\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
+"Generated-By: Babel 2.0\n"
 "X-Generator: Zanata 3.7.1\n"
 
 #, python-format
index f6e0fab..123379c 100644 (file)
@@ -8,18 +8,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 9.0.0.dev14\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-24 06:09+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-09-03 12:54+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Korean (Korea) (http://www.transifex.com/openstack/keystone/"
-"language/ko_KR/)\n"
+"Language: ko_KR\n"
+"Language-Team: Korean (South Korea)\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 2.0\n"
+"Generated-By: Babel 2.1.1\n"
 
 #, python-format
 msgid "%(detail)s"
index 0d4ec21..c57f0c5 100644 (file)
@@ -6,20 +6,19 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 8.0.0.0b4.dev56\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-21 06:08+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2014-08-31 03:19+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Polish (Poland) (http://www.transifex.com/openstack/keystone/"
-"language/pl_PL/)\n"
+"Language-Team: Polish (Poland)\n"
 "Language: pl-PL\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
 "|| n%100>=20) ? 1 : 2);\n"
+"Generated-By: Babel 2.0\n"
 "X-Generator: Zanata 3.7.1\n"
 
 #, python-format
index cda7507..f3b25b5 100644 (file)
@@ -6,19 +6,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 8.0.0.0b4.dev56\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-21 06:08+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2014-08-31 03:19+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Portuguese (Brazil) (http://www.transifex.com/openstack/"
-"keystone/language/pt_BR/)\n"
+"Language-Team: Portuguese (Brazil)\n"
 "Language: pt-BR\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"Generated-By: Babel 2.0\n"
 "X-Generator: Zanata 3.7.1\n"
 
 #, python-format
index f56ca03..2302f6a 100644 (file)
@@ -6,19 +6,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 8.0.0.0b4.dev56\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-21 06:08+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-06-26 05:13+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Portuguese (Brazil) (http://www.transifex.com/openstack/"
-"keystone/language/pt_BR/)\n"
+"Language-Team: Portuguese (Brazil)\n"
 "Language: pt-BR\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"Generated-By: Babel 2.0\n"
 "X-Generator: Zanata 3.7.1\n"
 
 msgid ""
index 9adc7d8..8bda14f 100644 (file)
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 9.0.0.dev14\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-24 06:09+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-09-03 12:54+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Portuguese (Brazil) (http://www.transifex.com/openstack/"
-"keystone/language/pt_BR/)\n"
+"Language: pt_BR\n"
+"Language-Team: Portuguese (Brazil)\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 2.0\n"
+"Generated-By: Babel 2.1.1\n"
 
 #, python-format
 msgid "%(detail)s"
index 4ec0cb4..9435231 100644 (file)
@@ -3,23 +3,24 @@
 # This file is distributed under the same license as the keystone project.
 #
 # Translators:
+# OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: Keystone\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-08-06 06:28+0000\n"
-"PO-Revision-Date: 2014-08-31 15:19+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
+"PO-Revision-Date: 2014-08-31 03:19+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Russian (http://www.transifex.com/openstack/keystone/language/"
-"ru/)\n"
+"Language-Team: Russian\n"
 "Language: ru\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
 "%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
 "%100>=11 && n%100<=14)? 2 : 3);\n"
+"Generated-By: Babel 2.0\n"
+"X-Generator: Zanata 3.7.1\n"
 
 #, python-format
 msgid "Unable to open template file %s"
index 31b8e98..1188d31 100644 (file)
@@ -9,20 +9,20 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 9.0.0.dev14\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-24 06:09+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-09-03 12:54+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Russian (http://www.transifex.com/openstack/keystone/language/"
-"ru/)\n"
+"Language: ru\n"
+"Language-Team: Russian\n"
 "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
 "%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
 "%100>=11 && n%100<=14)? 2 : 3)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
+"Generated-By: Babel 2.1.1\n"
 
 #, python-format
 msgid "%(detail)s"
index 78c74c7..4c59ad0 100644 (file)
@@ -6,19 +6,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 8.0.0.0b4.dev56\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-21 06:08+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-08-04 01:49+0000\n"
 "Last-Translator: İşbaran Akçayır <isbaran@gmail.com>\n"
-"Language-Team: Turkish (Turkey) (http://www.transifex.com/openstack/keystone/"
-"language/tr_TR/)\n"
+"Language-Team: Turkish (Turkey)\n"
 "Language: tr-TR\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
+"Generated-By: Babel 2.0\n"
 "X-Generator: Zanata 3.7.1\n"
 
 #, python-format
index dd35769..de59991 100644 (file)
@@ -6,19 +6,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 8.0.0.0b4.dev56\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-21 06:08+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-08-04 01:50+0000\n"
 "Last-Translator: İşbaran Akçayır <isbaran@gmail.com>\n"
-"Language-Team: Turkish (Turkey) (http://www.transifex.com/openstack/keystone/"
-"language/tr_TR/)\n"
+"Language-Team: Turkish (Turkey)\n"
 "Language: tr-TR\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
+"Generated-By: Babel 2.0\n"
 "X-Generator: Zanata 3.7.1\n"
 
 msgid "Cannot retrieve Authorization headers"
index 65f66f3..a345113 100644 (file)
@@ -6,19 +6,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 8.0.0.0b4.dev56\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-21 06:08+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-08-04 01:49+0000\n"
 "Last-Translator: İşbaran Akçayır <isbaran@gmail.com>\n"
-"Language-Team: Turkish (Turkey) (http://www.transifex.com/openstack/keystone/"
-"language/tr_TR/)\n"
+"Language-Team: Turkish (Turkey)\n"
 "Language: tr-TR\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
+"Generated-By: Babel 2.0\n"
 "X-Generator: Zanata 3.7.1\n"
 
 #, python-format
index d15319e..aeae058 100644 (file)
@@ -6,19 +6,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 8.0.0.0b4.dev56\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-21 06:08+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-09-03 12:54+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Turkish (Turkey) (http://www.transifex.com/openstack/keystone/"
-"language/tr_TR/)\n"
+"Language-Team: Turkish (Turkey)\n"
 "Language: tr-TR\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
+"Generated-By: Babel 2.0\n"
 "X-Generator: Zanata 3.7.1\n"
 
 #, python-format
index 5a37831..3ded8a9 100644 (file)
@@ -9,18 +9,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 9.0.0.dev14\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-24 06:09+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-09-03 12:54+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Turkish (Turkey) (http://www.transifex.com/openstack/keystone/"
-"language/tr_TR/)\n"
+"Language: tr_TR\n"
+"Language-Team: Turkish (Turkey)\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 2.0\n"
+"Generated-By: Babel 2.1.1\n"
 
 #, python-format
 msgid "%(detail)s"
index 9f87b4e..44dbbe3 100644 (file)
@@ -6,19 +6,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 8.0.0.0b4.dev56\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-21 06:08+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2014-08-31 03:19+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Chinese (China) (http://www.transifex.com/openstack/keystone/"
-"language/zh_CN/)\n"
+"Language-Team: Chinese (China)\n"
 "Language: zh-CN\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
+"Generated-By: Babel 2.0\n"
 "X-Generator: Zanata 3.7.1\n"
 
 #, python-format
index 6017737..791681d 100644 (file)
@@ -8,19 +8,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 8.0.0.0b4.dev56\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-21 06:08+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-06-26 05:13+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Chinese (China) (http://www.transifex.com/openstack/keystone/"
-"language/zh_CN/)\n"
+"Language-Team: Chinese (China)\n"
 "Language: zh-CN\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
+"Generated-By: Babel 2.0\n"
 "X-Generator: Zanata 3.7.1\n"
 
 msgid "Cannot retrieve Authorization headers"
index 46a6fa2..8a75633 100644 (file)
@@ -7,19 +7,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 8.0.0.0b4.dev56\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-21 06:08+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-08-01 06:26+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Chinese (China) (http://www.transifex.com/openstack/keystone/"
-"language/zh_CN/)\n"
+"Language-Team: Chinese (China)\n"
 "Language: zh-CN\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
+"Generated-By: Babel 2.0\n"
 "X-Generator: Zanata 3.7.1\n"
 
 #, python-format
index 2a970c8..6479984 100644 (file)
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 9.0.0.dev14\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-24 06:09+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-09-03 12:54+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Chinese (China) (http://www.transifex.com/openstack/keystone/"
-"language/zh_CN/)\n"
+"Language: zh_Hans_CN\n"
+"Language-Team: Chinese (China)\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 2.0\n"
+"Generated-By: Babel 2.1.1\n"
 
 #, python-format
 msgid "%(detail)s"
index fda1266..0b7082e 100644 (file)
@@ -6,19 +6,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 8.0.0.0b4.dev56\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-21 06:08+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2014-08-31 03:19+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Chinese (Taiwan) (http://www.transifex.com/openstack/keystone/"
-"language/zh_TW/)\n"
+"Language-Team: Chinese (Taiwan)\n"
 "Language: zh-TW\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
+"Generated-By: Babel 2.0\n"
 "X-Generator: Zanata 3.7.1\n"
 
 #, python-format
index 7a51b29..0c01497 100644 (file)
@@ -7,18 +7,18 @@
 # OpenStack Infra <zanata@openstack.org>, 2015. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: keystone 9.0.0.dev14\n"
+"Project-Id-Version: keystone 8.0.1.dev11\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/keystone\n"
-"POT-Creation-Date: 2015-09-24 06:09+0000\n"
+"POT-Creation-Date: 2015-11-05 06:13+0000\n"
 "PO-Revision-Date: 2015-09-03 12:54+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
-"Language-Team: Chinese (Taiwan) (http://www.transifex.com/openstack/keystone/"
-"language/zh_TW/)\n"
+"Language: zh_Hant_TW\n"
+"Language-Team: Chinese (Taiwan)\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 2.0\n"
+"Generated-By: Babel 2.1.1\n"
 
 #, python-format
 msgid "%(detail)s"
index 60c4e02..4fbeb71 100644 (file)
@@ -90,9 +90,11 @@ class Tenant(controller.V2Controller):
 
         self.assert_admin(context)
         tenant_ref['id'] = tenant_ref.get('id', uuid.uuid4().hex)
+        initiator = notifications._get_request_audit_info(context)
         tenant = self.resource_api.create_project(
             tenant_ref['id'],
-            self._normalize_domain_id(context, tenant_ref))
+            self._normalize_domain_id(context, tenant_ref),
+            initiator)
         return {'tenant': self.v3_to_v2_project(tenant)}
 
     @controller.v2_deprecated
@@ -104,15 +106,17 @@ class Tenant(controller.V2Controller):
         clean_tenant = tenant.copy()
         clean_tenant.pop('domain_id', None)
         clean_tenant.pop('is_domain', None)
+        initiator = notifications._get_request_audit_info(context)
         tenant_ref = self.resource_api.update_project(
-            tenant_id, clean_tenant)
+            tenant_id, clean_tenant, initiator)
         return {'tenant': self.v3_to_v2_project(tenant_ref)}
 
     @controller.v2_deprecated
     def delete_project(self, context, tenant_id):
         self.assert_admin(context)
         self._assert_not_is_domain_project(tenant_id)
-        self.resource_api.delete_project(tenant_id)
+        initiator = notifications._get_request_audit_info(context)
+        self.resource_api.delete_project(tenant_id, initiator)
 
 
 @dependency.requires('resource_api')
index 6015107..6891c57 100644 (file)
@@ -841,6 +841,7 @@ class DomainConfigManager(manager.Manager):
             'user_attribute_ignore', 'user_default_project_id_attribute',
             'user_allow_create', 'user_allow_update', 'user_allow_delete',
             'user_enabled_emulation', 'user_enabled_emulation_dn',
+            'user_enabled_emulation_use_group_config',
             'user_additional_attribute_mapping', 'group_tree_dn',
             'group_filter', 'group_objectclass', 'group_id_attribute',
             'group_name_attribute', 'group_member_attribute',
index ec087c4..1ad8d50 100644 (file)
@@ -279,6 +279,16 @@ class BaseNotificationTest(test_v3.RestfulTestCase):
         self.assertEqual(event_type, audit['event_type'])
         self.assertTrue(audit['send_notification_called'])
 
+    def _assert_initiator_data_is_set(self, operation, resource_type, typeURI):
+        self.assertTrue(len(self._audits) > 0)
+        audit = self._audits[-1]
+        payload = audit['payload']
+        self.assertEqual(self.user_id, payload['initiator']['id'])
+        self.assertEqual(self.project_id, payload['initiator']['project_id'])
+        self.assertEqual(typeURI, payload['target']['typeURI'])
+        action = '%s.%s' % (operation, resource_type)
+        self.assertEqual(action, payload['action'])
+
     def _assert_notify_not_sent(self, resource_id, operation, resource_type,
                                 public=True):
         unexpected = {
@@ -633,11 +643,154 @@ class CADFNotificationsForEntities(NotificationsForEntities):
         resource_id = resp.result.get('domain').get('id')
         self._assert_last_audit(resource_id, CREATED_OPERATION, 'domain',
                                 cadftaxonomy.SECURITY_DOMAIN)
-        self.assertTrue(len(self._audits) > 0)
-        audit = self._audits[-1]
-        payload = audit['payload']
-        self.assertEqual(self.user_id, payload['initiator']['id'])
-        self.assertEqual(self.project_id, payload['initiator']['project_id'])
+        self._assert_initiator_data_is_set(CREATED_OPERATION,
+                                           'domain',
+                                           cadftaxonomy.SECURITY_DOMAIN)
+
+
+class V2Notifications(BaseNotificationTest):
+
+    def setUp(self):
+        super(V2Notifications, self).setUp()
+        self.config_fixture.config(notification_format='cadf')
+
+    def test_user(self):
+        token = self.get_scoped_token()
+        resp = self.admin_request(
+            method='POST',
+            path='/v2.0/users',
+            body={
+                'user': {
+                    'name': uuid.uuid4().hex,
+                    'password': uuid.uuid4().hex,
+                    'enabled': True,
+                },
+            },
+            token=token,
+        )
+        user_id = resp.result.get('user').get('id')
+        self._assert_initiator_data_is_set(CREATED_OPERATION,
+                                           'user',
+                                           cadftaxonomy.SECURITY_ACCOUNT_USER)
+        # test for delete user
+        self.admin_request(
+            method='DELETE',
+            path='/v2.0/users/%s' % user_id,
+            token=token,
+        )
+        self._assert_initiator_data_is_set(DELETED_OPERATION,
+                                           'user',
+                                           cadftaxonomy.SECURITY_ACCOUNT_USER)
+
+    def test_role(self):
+        token = self.get_scoped_token()
+        resp = self.admin_request(
+            method='POST',
+            path='/v2.0/OS-KSADM/roles',
+            body={
+                'role': {
+                    'name': uuid.uuid4().hex,
+                    'description': uuid.uuid4().hex,
+                },
+            },
+            token=token,
+        )
+        role_id = resp.result.get('role').get('id')
+        self._assert_initiator_data_is_set(CREATED_OPERATION,
+                                           'role',
+                                           cadftaxonomy.SECURITY_ROLE)
+        # test for delete role
+        self.admin_request(
+            method='DELETE',
+            path='/v2.0/OS-KSADM/roles/%s' % role_id,
+            token=token,
+        )
+        self._assert_initiator_data_is_set(DELETED_OPERATION,
+                                           'role',
+                                           cadftaxonomy.SECURITY_ROLE)
+
+    def test_service_and_endpoint(self):
+        token = self.get_scoped_token()
+        resp = self.admin_request(
+            method='POST',
+            path='/v2.0/OS-KSADM/services',
+            body={
+                'OS-KSADM:service': {
+                    'name': uuid.uuid4().hex,
+                    'type': uuid.uuid4().hex,
+                    'description': uuid.uuid4().hex,
+                },
+            },
+            token=token,
+        )
+        service_id = resp.result.get('OS-KSADM:service').get('id')
+        self._assert_initiator_data_is_set(CREATED_OPERATION,
+                                           'service',
+                                           cadftaxonomy.SECURITY_SERVICE)
+        resp = self.admin_request(
+            method='POST',
+            path='/v2.0/endpoints',
+            body={
+                'endpoint': {
+                    'region': uuid.uuid4().hex,
+                    'service_id': service_id,
+                    'publicurl': uuid.uuid4().hex,
+                    'adminurl': uuid.uuid4().hex,
+                    'internalurl': uuid.uuid4().hex,
+                },
+            },
+            token=token,
+        )
+        endpoint_id = resp.result.get('endpoint').get('id')
+        self._assert_initiator_data_is_set(CREATED_OPERATION,
+                                           'endpoint',
+                                           cadftaxonomy.SECURITY_ENDPOINT)
+        # test for delete endpoint
+        self.admin_request(
+            method='DELETE',
+            path='/v2.0/endpoints/%s' % endpoint_id,
+            token=token,
+        )
+        self._assert_initiator_data_is_set(DELETED_OPERATION,
+                                           'endpoint',
+                                           cadftaxonomy.SECURITY_ENDPOINT)
+        # test for delete service
+        self.admin_request(
+            method='DELETE',
+            path='/v2.0/OS-KSADM/services/%s' % service_id,
+            token=token,
+        )
+        self._assert_initiator_data_is_set(DELETED_OPERATION,
+                                           'service',
+                                           cadftaxonomy.SECURITY_SERVICE)
+
+    def test_project(self):
+        token = self.get_scoped_token()
+        resp = self.admin_request(
+            method='POST',
+            path='/v2.0/tenants',
+            body={
+                'tenant': {
+                    'name': uuid.uuid4().hex,
+                    'description': uuid.uuid4().hex,
+                    'enabled': True
+                },
+            },
+            token=token,
+        )
+        project_id = resp.result.get('tenant').get('id')
+        self._assert_initiator_data_is_set(CREATED_OPERATION,
+                                           'project',
+                                           cadftaxonomy.SECURITY_PROJECT)
+        # test for delete project
+        self.admin_request(
+            method='DELETE',
+            path='/v2.0/tenants/%s' % project_id,
+            token=token,
+        )
+        self._assert_initiator_data_is_set(DELETED_OPERATION,
+                                           'project',
+                                           cadftaxonomy.SECURITY_PROJECT)
 
 
 class TestEventCallbacks(test_v3.RestfulTestCase):
index da24019..35b47e2 100644 (file)
@@ -114,7 +114,7 @@ class RestfulTestCase(unit.TestCase):
 
         example::
 
-            self.assertResponseStatus(response, http_client.NO_CONTENT)
+            self.assertResponseStatus(response, 204)
         """
         self.assertEqual(
             response.status_code,
index 4c57454..24fc82d 100644 (file)
@@ -48,7 +48,8 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
         Valid endpoint and project id test case.
 
         """
-        self.put(self.default_request_url)
+        self.put(self.default_request_url,
+                 expected_status=204)
 
     def test_create_endpoint_project_association_with_invalid_project(self):
         """PUT OS-EP-FILTER/projects/{project_id}/endpoints/{endpoint_id}
@@ -81,7 +82,8 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
 
         """
         self.put(self.default_request_url,
-                 body={'project_id': self.default_domain_project_id})
+                 body={'project_id': self.default_domain_project_id},
+                 expected_status=204)
 
     def test_check_endpoint_project_association(self):
         """HEAD /OS-EP-FILTER/projects/{project_id}/endpoints/{endpoint_id}
@@ -89,11 +91,13 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
         Valid project and endpoint id test case.
 
         """
-        self.put(self.default_request_url)
+        self.put(self.default_request_url,
+                 expected_status=204)
         self.head('/OS-EP-FILTER/projects/%(project_id)s'
                   '/endpoints/%(endpoint_id)s' % {
                       'project_id': self.default_domain_project_id,
-                      'endpoint_id': self.endpoint_id})
+                      'endpoint_id': self.endpoint_id},
+                  expected_status=204)
 
     def test_check_endpoint_project_association_with_invalid_project(self):
         """HEAD /OS-EP-FILTER/projects/{project_id}/endpoints/{endpoint_id}
@@ -165,7 +169,8 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
 
         """
         r = self.get('/OS-EP-FILTER/endpoints/%(endpoint_id)s/projects' %
-                     {'endpoint_id': self.endpoint_id})
+                     {'endpoint_id': self.endpoint_id},
+                     expected_status=200)
         self.assertValidProjectListResponse(r, expected_length=0)
 
     def test_list_projects_associated_with_invalid_endpoint(self):
@@ -188,7 +193,8 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
         self.delete('/OS-EP-FILTER/projects/%(project_id)s'
                     '/endpoints/%(endpoint_id)s' % {
                         'project_id': self.default_domain_project_id,
-                        'endpoint_id': self.endpoint_id})
+                        'endpoint_id': self.endpoint_id},
+                    expected_status=204)
 
     def test_remove_endpoint_project_association_with_invalid_project(self):
         """DELETE /OS-EP-FILTER/projects/{project_id}/endpoints/{endpoint_id}
@@ -220,26 +226,26 @@ class EndpointFilterCRUDTestCase(TestExtensionCase):
         self.put(self.default_request_url)
         association_url = ('/OS-EP-FILTER/endpoints/%(endpoint_id)s/projects' %
                            {'endpoint_id': self.endpoint_id})
-        r = self.get(association_url)
+        r = self.get(association_url, expected_status=200)
         self.assertValidProjectListResponse(r, expected_length=1)
 
         self.delete('/projects/%(project_id)s' % {
             'project_id': self.default_domain_project_id})
 
-        r = self.get(association_url)
+        r = self.get(association_url, expected_status=200)
         self.assertValidProjectListResponse(r, expected_length=0)
 
     def test_endpoint_project_association_cleanup_when_endpoint_deleted(self):
         self.put(self.default_request_url)
         association_url = '/OS-EP-FILTER/projects/%(project_id)s/endpoints' % {
             'project_id': self.default_domain_project_id}
-        r = self.get(association_url)
+        r = self.get(association_url, expected_status=200)
         self.assertValidEndpointListResponse(r, expected_length=1)
 
         self.delete('/endpoints/%(endpoint_id)s' % {
             'endpoint_id': self.endpoint_id})
 
-        r = self.get(association_url)
+        r = self.get(association_url, expected_status=200)
         self.assertValidEndpointListResponse(r, expected_length=0)
 
 
@@ -270,7 +276,8 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
         self.put('/OS-EP-FILTER/projects/%(project_id)s'
                  '/endpoints/%(endpoint_id)s' % {
                      'project_id': project['id'],
-                     'endpoint_id': self.endpoint_id})
+                     'endpoint_id': self.endpoint_id},
+                 expected_status=204)
 
         # attempt to authenticate without requesting a project
         auth_data = self.build_authentication_request(
@@ -290,7 +297,8 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
         self.put('/OS-EP-FILTER/projects/%(project_id)s'
                  '/endpoints/%(endpoint_id)s' % {
                      'project_id': self.project['id'],
-                     'endpoint_id': self.endpoint_id})
+                     'endpoint_id': self.endpoint_id},
+                 expected_status=204)
 
         auth_data = self.build_authentication_request(
             user_id=self.user['id'],
@@ -310,7 +318,8 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
         self.put('/OS-EP-FILTER/projects/%(project_id)s'
                  '/endpoints/%(endpoint_id)s' % {
                      'project_id': self.project['id'],
-                     'endpoint_id': self.endpoint_id})
+                     'endpoint_id': self.endpoint_id},
+                 expected_status=204)
 
         auth_data = self.build_authentication_request(
             user_id=self.user['id'],
@@ -329,7 +338,8 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
         self.put('/OS-EP-FILTER/projects/%(project_id)s'
                  '/endpoints/%(endpoint_id)s' % {
                      'project_id': self.project['id'],
-                     'endpoint_id': self.endpoint_id})
+                     'endpoint_id': self.endpoint_id},
+                 expected_status=204)
 
         # create a second temporary endpoint
         self.endpoint_id2 = uuid.uuid4().hex
@@ -343,7 +353,8 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
         self.put('/OS-EP-FILTER/projects/%(project_id)s'
                  '/endpoints/%(endpoint_id)s' % {
                      'project_id': self.project['id'],
-                     'endpoint_id': self.endpoint_id2})
+                     'endpoint_id': self.endpoint_id2},
+                 expected_status=204)
 
         # remove the temporary reference
         # this will create inconsistency in the endpoint filter table
@@ -369,7 +380,8 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
         self.put('/OS-EP-FILTER/projects/%(project_id)s'
                  '/endpoints/%(endpoint_id)s' % {
                      'project_id': self.project['id'],
-                     'endpoint_id': self.endpoint_id})
+                     'endpoint_id': self.endpoint_id},
+                 expected_status=204)
 
         # Add a disabled endpoint to the default project.
 
@@ -387,7 +399,8 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
         self.put('/OS-EP-FILTER/projects/%(project_id)s'
                  '/endpoints/%(endpoint_id)s' % {
                      'project_id': self.project['id'],
-                     'endpoint_id': disabled_endpoint_id})
+                     'endpoint_id': disabled_endpoint_id},
+                 expected_status=204)
 
         # Authenticate to get token with catalog
         auth_data = self.build_authentication_request(
@@ -416,11 +429,13 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
         self.put('/OS-EP-FILTER/projects/%(project_id)s'
                  '/endpoints/%(endpoint_id)s' % {
                      'project_id': self.project['id'],
-                     'endpoint_id': endpoint_id1})
+                     'endpoint_id': endpoint_id1},
+                 expected_status=204)
         self.put('/OS-EP-FILTER/projects/%(project_id)s'
                  '/endpoints/%(endpoint_id)s' % {
                      'project_id': self.project['id'],
-                     'endpoint_id': endpoint_id2})
+                     'endpoint_id': endpoint_id2},
+                 expected_status=204)
 
         # there should be only two endpoints in token catalog
         auth_data = self.build_authentication_request(
@@ -439,7 +454,8 @@ class EndpointFilterTokenRequestTestCase(TestExtensionCase):
         self.put('/OS-EP-FILTER/projects/%(project_id)s'
                  '/endpoints/%(endpoint_id)s' % {
                      'project_id': self.project['id'],
-                     'endpoint_id': self.endpoint_id})
+                     'endpoint_id': self.endpoint_id},
+                 expected_status=204)
 
         auth_data = self.build_authentication_request(
             user_id=self.user['id'],
@@ -622,7 +638,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
             self.DEFAULT_ENDPOINT_GROUP_URL, self.DEFAULT_ENDPOINT_GROUP_BODY)
         url = '/OS-EP-FILTER/endpoint_groups/%(endpoint_group_id)s' % {
             'endpoint_group_id': endpoint_group_id}
-        self.head(url, expected_status=http_client.OK)
+        self.head(url, expected_status=200)
 
     def test_check_invalid_endpoint_group(self):
         """HEAD /OS-EP-FILTER/endpoint_groups/{endpoint_group_id}
@@ -816,7 +832,7 @@ class EndpointGroupCRUDTestCase(TestExtensionCase):
                                                         self.project_id)
         url = self._get_project_endpoint_group_url(
             endpoint_group_id, self.project_id)
-        self.head(url, expected_status=http_client.OK)
+        self.head(url, expected_status=200)
 
     def test_check_endpoint_group_to_project_with_invalid_project_id(self):
         """Test HEAD with an invalid endpoint group and project association."""
index d3b51ed..302fc2c 100644 (file)
@@ -4671,7 +4671,7 @@ class TokenTests(object):
 
     def test_list_revoked_tokens_for_multiple_tokens(self):
         self.check_list_revoked_tokens([self.delete_token()
-                                        for x in range(2)])
+                                        for x in six.moves.range(2)])
 
     def test_flush_expired_token(self):
         token_id = uuid.uuid4().hex
index 808922a..d96ec37 100644 (file)
@@ -21,7 +21,6 @@ import ldap
 import mock
 from oslo_config import cfg
 import pkg_resources
-from six.moves import http_client
 from six.moves import range
 from testtools import matchers
 
@@ -2182,6 +2181,26 @@ class LDAPIdentityEnabledEmulation(LDAPIdentity):
         self.skipTest(
             "Enabled emulation conflicts with enabled mask")
 
+    def test_user_enabled_use_group_config(self):
+        self.config_fixture.config(
+            group='ldap',
+            user_enabled_emulation_use_group_config=True,
+            group_member_attribute='uniqueMember',
+            group_objectclass='groupOfUniqueNames')
+        self.ldapdb.clear()
+        self.load_backends()
+        self.load_fixtures(default_fixtures)
+
+        # Create a user and ensure they are enabled.
+        user1 = {'name': u'fäké1', 'enabled': True,
+                 'domain_id': CONF.identity.default_domain_id}
+        user_ref = self.identity_api.create_user(user1)
+        self.assertIs(True, user_ref['enabled'])
+
+        # Get a user and ensure they are enabled.
+        user_ref = self.identity_api.get_user(user_ref['id'])
+        self.assertIs(True, user_ref['enabled'])
+
     def test_user_enabled_invert(self):
         self.config_fixture.config(group='ldap', user_enabled_invert=True,
                                    user_enabled_default=False)
@@ -2487,7 +2506,7 @@ class BaseMultiLDAPandSQLIdentity(object):
             self.identity_api._get_domain_driver_and_entity_id(
                 user['id']))
 
-        if expected_status == http_client.OK:
+        if expected_status == 200:
             ref = driver.get_user(entity_id)
             ref = self.identity_api._set_domain_id_and_mapping(
                 ref, domain_id, driver, map.EntityType.USER)
@@ -2661,23 +2680,21 @@ class MultiLDAPandSQLIdentity(BaseLDAPIdentity, unit.SQLDriverOverrides,
 
         check_user = self.check_user
         check_user(self.users['user0'],
-                   self.domains['domain_default']['id'], http_client.OK)
+                   self.domains['domain_default']['id'], 200)
         for domain in [self.domains['domain1']['id'],
                        self.domains['domain2']['id'],
                        self.domains['domain3']['id'],
                        self.domains['domain4']['id']]:
             check_user(self.users['user0'], domain, exception.UserNotFound)
 
-        check_user(self.users['user1'], self.domains['domain1']['id'],
-                   http_client.OK)
+        check_user(self.users['user1'], self.domains['domain1']['id'], 200)
         for domain in [self.domains['domain_default']['id'],
                        self.domains['domain2']['id'],
                        self.domains['domain3']['id'],
                        self.domains['domain4']['id']]:
             check_user(self.users['user1'], domain, exception.UserNotFound)
 
-        check_user(self.users['user2'], self.domains['domain2']['id'],
-                   http_client.OK)
+        check_user(self.users['user2'], self.domains['domain2']['id'], 200)
         for domain in [self.domains['domain_default']['id'],
                        self.domains['domain1']['id'],
                        self.domains['domain3']['id'],
@@ -2687,14 +2704,10 @@ class MultiLDAPandSQLIdentity(BaseLDAPIdentity, unit.SQLDriverOverrides,
         # domain3 and domain4 share the same backend, so you should be
         # able to see user3 and user4 from either.
 
-        check_user(self.users['user3'], self.domains['domain3']['id'],
-                   http_client.OK)
-        check_user(self.users['user3'], self.domains['domain4']['id'],
-                   http_client.OK)
-        check_user(self.users['user4'], self.domains['domain3']['id'],
-                   http_client.OK)
-        check_user(self.users['user4'], self.domains['domain4']['id'],
-                   http_client.OK)
+        check_user(self.users['user3'], self.domains['domain3']['id'], 200)
+        check_user(self.users['user3'], self.domains['domain4']['id'], 200)
+        check_user(self.users['user4'], self.domains['domain3']['id'], 200)
+        check_user(self.users['user4'], self.domains['domain4']['id'], 200)
 
         for domain in [self.domains['domain_default']['id'],
                        self.domains['domain1']['id'],
@@ -3151,12 +3164,12 @@ class DomainSpecificLDAPandSQLIdentity(
         # driver, but won't find it via any other domain driver
 
         self.check_user(self.users['user0'],
-                        self.domains['domain_default']['id'], http_client.OK)
+                        self.domains['domain_default']['id'], 200)
         self.check_user(self.users['user0'],
                         self.domains['domain1']['id'], exception.UserNotFound)
 
         self.check_user(self.users['user1'],
-                        self.domains['domain1']['id'], http_client.OK)
+                        self.domains['domain1']['id'], 200)
         self.check_user(self.users['user1'],
                         self.domains['domain_default']['id'],
                         exception.UserNotFound)
index 85acfed..ada2de4 100644 (file)
@@ -53,8 +53,7 @@ class V2CatalogTestCase(rest.RestfulTestCase):
         """Applicable only to JSON."""
         return r.result['access']['token']['id']
 
-    def _endpoint_create(self, expected_status=http_client.OK,
-                         service_id=SERVICE_FIXTURE,
+    def _endpoint_create(self, expected_status=200, service_id=SERVICE_FIXTURE,
                          publicurl='http://localhost:8080',
                          internalurl='http://localhost:8080',
                          adminurl='http://localhost:8080'):
@@ -77,6 +76,18 @@ class V2CatalogTestCase(rest.RestfulTestCase):
                                body=body)
         return body, r
 
+    def _region_create(self):
+        region_id = uuid.uuid4().hex
+        self.catalog_api.create_region({'id': region_id})
+        return region_id
+
+    def _service_create(self):
+        service_id = uuid.uuid4().hex
+        service = unit.new_service_ref()
+        service['id'] = service_id
+        self.catalog_api.create_service(service_id, service)
+        return service_id
+
     def test_endpoint_create(self):
         req_body, response = self._endpoint_create()
         self.assertIn('endpoint', response.result)
@@ -84,6 +95,78 @@ class V2CatalogTestCase(rest.RestfulTestCase):
         for field, value in req_body['endpoint'].items():
             self.assertEqual(response.result['endpoint'][field], value)
 
+    def test_pure_v3_endpoint_with_publicurl_visible_from_v2(self):
+        """Test pure v3 endpoint can be fetched via v2 API.
+
+        For those who are using v2 APIs, endpoints created by v3 API should
+        also be visible as there are no differences about the endpoints
+        except the format or the internal implementation.
+        And because public url is required for v2 API, so only the v3 endpoints
+        of the service which has the public interface endpoint will be
+        converted into v2 endpoints.
+        """
+        region_id = self._region_create()
+        service_id = self._service_create()
+        # create a v3 endpoint with three interfaces
+        body = {
+            'endpoint': unit.new_endpoint_ref(service_id,
+                                              default_region_id=region_id)
+        }
+        for interface in catalog.controllers.INTERFACES:
+            body['endpoint']['interface'] = interface
+            self.admin_request(method='POST',
+                               token=self.get_scoped_token(),
+                               path='/v3/endpoints',
+                               expected_status=http_client.CREATED,
+                               body=body)
+
+        r = self.admin_request(token=self.get_scoped_token(),
+                               path='/v2.0/endpoints')
+        # v3 endpoints having public url can be fetched via v2.0 API
+        self.assertEqual(1, len(r.result['endpoints']))
+        v2_endpoint = r.result['endpoints'][0]
+        self.assertEqual(service_id, v2_endpoint['service_id'])
+        # check urls just in case.
+        # This is not the focus of this test, so no different urls are used.
+        self.assertEqual(body['endpoint']['url'], v2_endpoint['publicurl'])
+        self.assertEqual(body['endpoint']['url'], v2_endpoint['adminurl'])
+        self.assertEqual(body['endpoint']['url'], v2_endpoint['internalurl'])
+        self.assertNotIn('name', v2_endpoint)
+
+        v3_endpoint = self.catalog_api.get_endpoint(v2_endpoint['id'])
+        # it's the v3 public endpoint's id as the generated v2 endpoint
+        self.assertEqual('public', v3_endpoint['interface'])
+        self.assertEqual(service_id, v3_endpoint['service_id'])
+
+    def test_pure_v3_endpoint_without_publicurl_invisible_from_v2(self):
+        """Test pure v3 endpoint without public url can't be fetched via v2 API.
+
+        V2 API will return endpoints created by v3 API, but because public url
+        is required for v2 API, so v3 endpoints without public url will be
+        ignored.
+        """
+        region_id = self._region_create()
+        service_id = self._service_create()
+        # create a v3 endpoint without public interface
+        body = {
+            'endpoint': unit.new_endpoint_ref(service_id,
+                                              default_region_id=region_id)
+        }
+        for interface in catalog.controllers.INTERFACES:
+            if interface == 'public':
+                continue
+            body['endpoint']['interface'] = interface
+            self.admin_request(method='POST',
+                               token=self.get_scoped_token(),
+                               path='/v3/endpoints',
+                               expected_status=http_client.CREATED,
+                               body=body)
+
+        r = self.admin_request(token=self.get_scoped_token(),
+                               path='/v2.0/endpoints')
+        # v3 endpoints without public url won't be fetched via v2.0 API
+        self.assertEqual(0, len(r.result['endpoints']))
+
     def test_endpoint_create_with_null_adminurl(self):
         req_body, response = self._endpoint_create(adminurl=None)
         self.assertIsNone(req_body['endpoint']['adminurl'])
@@ -126,7 +209,7 @@ class V2CatalogTestCase(rest.RestfulTestCase):
         valid_url = 'http://127.0.0.1:8774/v1.1/$(tenant_id)s'
 
         # baseline tests that all valid URLs works
-        self._endpoint_create(expected_status=http_client.OK,
+        self._endpoint_create(expected_status=200,
                               publicurl=valid_url,
                               internalurl=valid_url,
                               adminurl=valid_url)
index 47a9981..769e7c8 100644 (file)
@@ -17,7 +17,6 @@ import os
 import shutil
 
 import mock
-from six.moves import http_client
 from testtools import matchers
 
 from keystone.common import environment
@@ -114,13 +113,11 @@ class CertSetupTestCase(rest.RestfulTestCase):
         # requests don't have some of the normal information
         signing_resp = self.request(self.public_app,
                                     '/v2.0/certificates/signing',
-                                    method='GET',
-                                    expected_status=http_client.OK)
+                                    method='GET', expected_status=200)
 
         cacert_resp = self.request(self.public_app,
                                    '/v2.0/certificates/ca',
-                                   method='GET',
-                                   expected_status=http_client.OK)
+                                   method='GET', expected_status=200)
 
         with open(CONF.signing.certfile) as f:
             self.assertEqual(f.read(), signing_resp.text)
@@ -136,7 +133,7 @@ class CertSetupTestCase(rest.RestfulTestCase):
             for accept in [None, 'text/html', 'application/json', 'text/xml']:
                 headers = {'Accept': accept} if accept else {}
                 resp = self.request(self.public_app, path, method='GET',
-                                    expected_status=http_client.OK,
+                                    expected_status=200,
                                     headers=headers)
 
                 self.assertEqual('text/html', resp.content_type)
@@ -149,7 +146,7 @@ class CertSetupTestCase(rest.RestfulTestCase):
     def test_failure(self):
         for path in ['/v2.0/certificates/signing', '/v2.0/certificates/ca']:
             self.request(self.public_app, path, method='GET',
-                         expected_status=http_client.INTERNAL_SERVER_ERROR)
+                         expected_status=500)
 
     def test_pki_certs_rebuild(self):
         self.test_create_pki_certs()
index b241b41..8664e2c 100644 (file)
@@ -12,8 +12,6 @@
 
 import uuid
 
-from six.moves import http_client
-
 from keystone.tests.unit import test_v3
 
 
@@ -33,7 +31,7 @@ class TestSimpleCert(BaseTestCase):
                                 method='GET',
                                 path=path,
                                 headers={'Accept': content_type},
-                                expected_status=http_client.OK)
+                                expected_status=200)
 
         self.assertEqual(content_type, response.content_type.lower())
         self.assertIn('---BEGIN', response.body)
@@ -56,4 +54,4 @@ class TestSimpleCert(BaseTestCase):
             self.request(app=self.public_app,
                          method='GET',
                          path=path,
-                         expected_status=http_client.INTERNAL_SERVER_ERROR)
+                         expected_status=500)
index b2f0e52..686e2b7 100644 (file)
 import json
 import os
 
-import mock
 from oslo_policy import policy as common_policy
 import six
-from six.moves.urllib import request as urlrequest
 from testtools import matchers
 
 from keystone import exception
@@ -118,28 +116,6 @@ class PolicyTestCase(BasePolicyTestCase):
         action = "example:allowed"
         rules.enforce(self.credentials, action, self.target)
 
-    def test_enforce_http_true(self):
-
-        def fakeurlopen(url, post_data):
-            return six.StringIO("True")
-
-        action = "example:get_http"
-        target = {}
-        with mock.patch.object(urlrequest, 'urlopen', fakeurlopen):
-            result = rules.enforce(self.credentials, action, target)
-        self.assertTrue(result)
-
-    def test_enforce_http_false(self):
-
-        def fakeurlopen(url, post_data):
-            return six.StringIO("False")
-
-        action = "example:get_http"
-        target = {}
-        with mock.patch.object(urlrequest, 'urlopen', fakeurlopen):
-            self.assertRaises(exception.ForbiddenAction, rules.enforce,
-                              self.credentials, action, target)
-
     def test_templatized_enforcement(self):
         target_mine = {'project_id': 'fake'}
         target_not_mine = {'project_id': 'another'}
index 87b3d48..f498fe9 100644 (file)
@@ -180,6 +180,7 @@ class FederationExtension(test_sql_upgrade.SqlMigrateBase):
         self.federation_protocol = 'federation_protocol'
         self.service_provider = 'service_provider'
         self.mapping = 'mapping'
+        self.remote_id_table = 'idp_remote_ids'
 
     def repo_package(self):
         return federation
@@ -310,6 +311,68 @@ class FederationExtension(test_sql_upgrade.SqlMigrateBase):
         self.assertEqual('', sp.auth_url)
         self.assertEqual('', sp.sp_url)
 
+    def test_propagate_remote_id_to_separate_column(self):
+        """Make sure empty remote_id is not propagated.
+        Test scenario:
+        - Upgrade database to version 6 where identity_provider table has a
+          remote_id column
+        - Add 3 identity provider objects, where idp1 and idp2 have valid
+          remote_id parameter set, and idp3 has it empty (None).
+        - Upgrade database to version 7 and expect migration scripts to
+          properly move data rom identity_provider.remote_id column into
+          separate table idp_remote_ids.
+        - In the idp_remote_ids table expect to find entries for idp1 and idp2
+          and not find anything for idp3 (identitified by idp's id)
+
+        """
+        session = self.Session()
+        idp1 = {'id': uuid.uuid4().hex,
+                'remote_id': uuid.uuid4().hex,
+                'description': uuid.uuid4().hex,
+                'enabled': True}
+        idp2 = {'id': uuid.uuid4().hex,
+                'remote_id': uuid.uuid4().hex,
+                'description': uuid.uuid4().hex,
+                'enabled': True}
+        idp3 = {'id': uuid.uuid4().hex,
+                'remote_id': None,
+                'description': uuid.uuid4().hex,
+                'enabled': True}
+        self.upgrade(6, repository=self.repo_path)
+        self.assertTableColumns(self.identity_provider,
+                                ['id', 'description', 'enabled', 'remote_id'])
+
+        self.insert_dict(session, self.identity_provider, idp1)
+        self.insert_dict(session, self.identity_provider, idp2)
+        self.insert_dict(session, self.identity_provider, idp3)
+
+        session.close()
+        self.upgrade(7, repository=self.repo_path)
+
+        self.assertTableColumns(self.identity_provider,
+                                ['id', 'description', 'enabled'])
+        remote_id_table = sqlalchemy.Table(self.remote_id_table,
+                                           self.metadata,
+                                           autoload=True)
+
+        session = self.Session()
+        self.metadata.clear()
+
+        idp = session.query(remote_id_table).filter(
+            remote_id_table.c.idp_id == idp1['id'])[0]
+        self.assertEqual(idp1['remote_id'], idp.remote_id)
+
+        idp = session.query(remote_id_table).filter(
+            remote_id_table.c.idp_id == idp2['id'])[0]
+        self.assertEqual(idp2['remote_id'], idp.remote_id)
+
+        idp = session.query(remote_id_table).filter(
+            remote_id_table.c.idp_id == idp3['id'])
+        # NOTE(marek-denis): As idp3 had empty 'remote_id' attribute we expect
+        # not to find it in the 'remote_id_table' table, hence count should be
+        # 0.real
+        self.assertEqual(0, idp.count())
+
     def test_add_relay_state_column(self):
         self.upgrade(8, repository=self.repo_path)
         self.assertTableColumns(self.service_provider,
index 99b5a89..acdfca5 100644 (file)
@@ -132,7 +132,7 @@ class CoreApiTests(object):
                     'tenantId': self.tenant_bar['id'],
                 },
             },
-            expected_status=http_client.OK)
+            expected_status=200)
         self.assertValidAuthenticationResponse(r, require_service_catalog=True)
 
     def test_authenticate_unscoped(self):
@@ -147,7 +147,7 @@ class CoreApiTests(object):
                     },
                 },
             },
-            expected_status=http_client.OK)
+            expected_status=200)
         self.assertValidAuthenticationResponse(r)
 
     def test_get_tenants_for_token(self):
@@ -234,7 +234,7 @@ class CoreApiTests(object):
                 'token_id': token,
             },
             token=token,
-            expected_status=http_client.OK)
+            expected_status=200)
 
     def test_endpoints(self):
         token = self.get_scoped_token()
@@ -370,7 +370,7 @@ class CoreApiTests(object):
                                },
                            },
                            token=token,
-                           expected_status=http_client.OK)
+                           expected_status=200)
 
     def test_error_response(self):
         """This triggers assertValidErrorResponse by convention."""
@@ -459,7 +459,7 @@ class CoreApiTests(object):
                 },
             },
             token=token,
-            expected_status=http_client.OK)
+            expected_status=200)
 
         user_id = self._get_user_id(r.result)
 
@@ -470,7 +470,7 @@ class CoreApiTests(object):
                 'user_id': user_id
             },
             token=token,
-            expected_status=http_client.OK)
+            expected_status=200)
         self.assertEqual(CONF.member_role_name, self._get_role_name(r.result))
 
         # Create a new tenant
@@ -485,7 +485,7 @@ class CoreApiTests(object):
                 },
             },
             token=token,
-            expected_status=http_client.OK)
+            expected_status=200)
 
         project_id = self._get_project_id(r.result)
 
@@ -501,7 +501,7 @@ class CoreApiTests(object):
                 },
             },
             token=token,
-            expected_status=http_client.OK)
+            expected_status=200)
 
         # 'member_role' should be in new_tenant
         r = self.admin_request(
@@ -510,7 +510,7 @@ class CoreApiTests(object):
                 'user_id': user_id
             },
             token=token,
-            expected_status=http_client.OK)
+            expected_status=200)
         self.assertEqual('_member_', self._get_role_name(r.result))
 
         # 'member_role' should not be in tenant_bar any more
@@ -520,7 +520,7 @@ class CoreApiTests(object):
                 'user_id': user_id
             },
             token=token,
-            expected_status=http_client.OK)
+            expected_status=200)
         self.assertNoRoles(r.result)
 
     def test_update_user_with_invalid_tenant(self):
@@ -539,7 +539,7 @@ class CoreApiTests(object):
                 },
             },
             token=token,
-            expected_status=http_client.OK)
+            expected_status=200)
         user_id = self._get_user_id(r.result)
 
         # Update user with an invalid tenant
@@ -571,7 +571,7 @@ class CoreApiTests(object):
                 },
             },
             token=token,
-            expected_status=http_client.OK)
+            expected_status=200)
         user_id = self._get_user_id(r.result)
 
         # Update user with an invalid tenant
@@ -604,7 +604,7 @@ class CoreApiTests(object):
                 },
             },
             token=token,
-            expected_status=http_client.OK)
+            expected_status=200)
 
         user_id = self._get_user_id(r.result)
 
@@ -615,7 +615,7 @@ class CoreApiTests(object):
                 'user_id': user_id
             },
             token=token,
-            expected_status=http_client.OK)
+            expected_status=200)
         self.assertEqual(CONF.member_role_name, self._get_role_name(r.result))
 
         # Update user's tenant with old tenant id
@@ -630,7 +630,7 @@ class CoreApiTests(object):
                 },
             },
             token=token,
-            expected_status=http_client.OK)
+            expected_status=200)
 
         # 'member_role' should still be in tenant_bar
         r = self.admin_request(
@@ -639,7 +639,7 @@ class CoreApiTests(object):
                 'user_id': user_id
             },
             token=token,
-            expected_status=http_client.OK)
+            expected_status=200)
         self.assertEqual('_member_', self._get_role_name(r.result))
 
     def test_authenticating_a_user_with_no_password(self):
@@ -721,7 +721,7 @@ class LegacyV2UsernameTests(object):
             path='/v2.0/users',
             token=token,
             body=body,
-            expected_status=http_client.OK)
+            expected_status=200)
 
     def test_create_with_extra_username(self):
         """The response for creating a user will contain the extra fields."""
@@ -772,7 +772,7 @@ class LegacyV2UsernameTests(object):
                     'enabled': enabled,
                 },
             },
-            expected_status=http_client.OK)
+            expected_status=200)
 
         self.assertValidUserResponse(r)
 
@@ -802,7 +802,7 @@ class LegacyV2UsernameTests(object):
                     'enabled': enabled,
                 },
             },
-            expected_status=http_client.OK)
+            expected_status=200)
 
         self.assertValidUserResponse(r)
 
@@ -881,7 +881,7 @@ class LegacyV2UsernameTests(object):
                     'enabled': enabled,
                 },
             },
-            expected_status=http_client.OK)
+            expected_status=200)
 
         self.assertValidUserResponse(r)
 
@@ -911,7 +911,7 @@ class LegacyV2UsernameTests(object):
                     'enabled': enabled,
                 },
             },
-            expected_status=http_client.OK)
+            expected_status=200)
 
         self.assertValidUserResponse(r)
 
@@ -931,7 +931,7 @@ class LegacyV2UsernameTests(object):
                     'enabled': True,
                 },
             },
-            expected_status=http_client.OK)
+            expected_status=200)
 
         self.assertValidUserResponse(r)
 
@@ -956,7 +956,7 @@ class LegacyV2UsernameTests(object):
                     'enabled': enabled,
                 },
             },
-            expected_status=http_client.OK)
+            expected_status=200)
 
         self.assertValidUserResponse(r)
 
@@ -1200,7 +1200,7 @@ class V2TestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests):
             method='GET',
             path='/v2.0/tokens/revoked',
             token=token,
-            expected_status=http_client.OK)
+            expected_status=200)
         self.assertValidRevocationListResponse(r)
 
     def assertValidRevocationListResponse(self, response):
@@ -1231,7 +1231,7 @@ class V2TestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests):
             method='GET',
             path='/v2.0/tokens/revoked',
             token=token1,
-            expected_status=http_client.OK)
+            expected_status=200)
         signed_text = r.result['signed']
 
         data_json = cms.cms_verify(signed_text, CONF.signing.certfile,
@@ -1333,7 +1333,7 @@ class V2TestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests):
                     },
                 },
             },
-            expected_status=http_client.OK)
+            expected_status=200)
 
         # ensure password doesn't leak
         user_id = r.result['user']['id']
@@ -1341,7 +1341,7 @@ class V2TestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests):
             method='GET',
             path='/v2.0/users/%s' % user_id,
             token=token,
-            expected_status=http_client.OK)
+            expected_status=200)
         self.assertNotIn('OS-KSADM:password', r.result['user'])
 
     def test_updating_a_user_with_an_OSKSADM_password(self):
@@ -1360,7 +1360,7 @@ class V2TestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests):
                 },
             },
             token=token,
-            expected_status=http_client.OK)
+            expected_status=200)
 
         # successfully authenticate
         self.public_request(
@@ -1374,7 +1374,7 @@ class V2TestCase(RestfulTestCase, CoreApiTests, LegacyV2UsernameTests):
                     },
                 },
             },
-            expected_status=http_client.OK)
+            expected_status=200)
 
 
 class RevokeApiTestCase(V2TestCase):
@@ -1436,7 +1436,7 @@ class TestFernetTokenProviderV2(RestfulTestCase):
             method='GET',
             path=path,
             token=admin_token,
-            expected_status=http_client.OK)
+            expected_status=200)
 
     def test_authenticate_scoped_token(self):
         project_ref = self.new_project_ref()
@@ -1466,7 +1466,7 @@ class TestFernetTokenProviderV2(RestfulTestCase):
             method='GET',
             path=path,
             token=admin_token,
-            expected_status=http_client.OK)
+            expected_status=200)
 
     def test_token_authentication_and_validation(self):
         """Test token authentication for Fernet token provider.
@@ -1491,7 +1491,7 @@ class TestFernetTokenProviderV2(RestfulTestCase):
                     }
                 }
             },
-            expected_status=http_client.OK)
+            expected_status=200)
 
         token_id = self._get_token_id(r)
         path = ('/v2.0/tokens/%s?belongsTo=%s' % (token_id, project_ref['id']))
@@ -1500,7 +1500,7 @@ class TestFernetTokenProviderV2(RestfulTestCase):
             method='GET',
             path=path,
             token=CONF.admin_token,
-            expected_status=http_client.OK)
+            expected_status=200)
 
     def test_rescoped_tokens_maintain_original_expiration(self):
         project_ref = self.new_project_ref()
@@ -1522,7 +1522,7 @@ class TestFernetTokenProviderV2(RestfulTestCase):
             },
             # NOTE(lbragstad): This test may need to be refactored if Keystone
             # decides to disallow rescoping using a scoped token.
-            expected_status=http_client.OK)
+            expected_status=200)
         original_token = resp.result['access']['token']['id']
         original_expiration = resp.result['access']['token']['expires']
 
@@ -1537,7 +1537,7 @@ class TestFernetTokenProviderV2(RestfulTestCase):
                     }
                 }
             },
-            expected_status=http_client.OK)
+            expected_status=200)
         rescoped_token = resp.result['access']['token']['id']
         rescoped_expiration = resp.result['access']['token']['expires']
         self.assertNotEqual(original_token, rescoped_token)
index 8d6d9eb..2a3fad8 100644 (file)
@@ -1137,7 +1137,7 @@ class ClientDrivenTestCase(unit.TestCase):
         credentials, signature = self._generate_default_user_ec2_credentials()
         credentials['signature'] = signature
         resp, token = self._send_ec2_auth_request(credentials)
-        self.assertEqual(http_client.OK, resp.status_code)
+        self.assertEqual(200, resp.status_code)
         self.assertIn('access', token)
 
     def test_ec2_auth_success_trust(self):
@@ -1169,7 +1169,7 @@ class ClientDrivenTestCase(unit.TestCase):
             cred.access, cred.secret)
         credentials['signature'] = signature
         resp, token = self._send_ec2_auth_request(credentials)
-        self.assertEqual(http_client.OK, resp.status_code)
+        self.assertEqual(200, resp.status_code)
         self.assertEqual(trust_id, token['access']['trust']['id'])
         # TODO(shardy) we really want to check the roles and trustee
         # but because of where the stubbing happens we don't seem to
index 7afe6ad..32c5e29 100644 (file)
@@ -18,7 +18,6 @@ import uuid
 from oslo_config import cfg
 from oslo_serialization import jsonutils
 from oslo_utils import timeutils
-from six.moves import http_client
 from testtools import matchers
 
 from keystone import auth
@@ -412,7 +411,7 @@ class RestfulTestCase(unit.SQLDriverOverrides, rest.RestfulTestCase,
         r = self.v3_authenticate_token(auth)
         return r.headers.get('X-Subject-Token')
 
-    def v3_authenticate_token(self, auth, expected_status=http_client.CREATED):
+    def v3_authenticate_token(self, auth, expected_status=201):
         return self.admin_request(method='POST',
                                   path='/v3/auth/tokens',
                                   body=auth,
@@ -441,31 +440,42 @@ class RestfulTestCase(unit.SQLDriverOverrides, rest.RestfulTestCase,
 
         return self.admin_request(path=path, token=token, **kwargs)
 
-    def get(self, path, expected_status=http_client.OK, **kwargs):
-        return self.v3_request(path, method='GET',
-                               expected_status=expected_status, **kwargs)
+    def get(self, path, **kwargs):
+        r = self.v3_request(method='GET', path=path, **kwargs)
+        if 'expected_status' not in kwargs:
+            self.assertResponseStatus(r, 200)
+        return r
 
-    def head(self, path, expected_status=http_client.NO_CONTENT, **kwargs):
-        r = self.v3_request(path, method='HEAD',
-                            expected_status=expected_status, **kwargs)
+    def head(self, path, **kwargs):
+        r = self.v3_request(method='HEAD', path=path, **kwargs)
+        if 'expected_status' not in kwargs:
+            self.assertResponseStatus(r, 204)
         self.assertEqual('', r.body)
         return r
 
-    def post(self, path, expected_status=http_client.CREATED, **kwargs):
-        return self.v3_request(path, method='POST',
-                               expected_status=expected_status, **kwargs)
+    def post(self, path, **kwargs):
+        r = self.v3_request(method='POST', path=path, **kwargs)
+        if 'expected_status' not in kwargs:
+            self.assertResponseStatus(r, 201)
+        return r
 
-    def put(self, path, expected_status=http_client.NO_CONTENT, **kwargs):
-        return self.v3_request(path, method='PUT',
-                               expected_status=expected_status, **kwargs)
+    def put(self, path, **kwargs):
+        r = self.v3_request(method='PUT', path=path, **kwargs)
+        if 'expected_status' not in kwargs:
+            self.assertResponseStatus(r, 204)
+        return r
 
-    def patch(self, path, expected_status=http_client.OK, **kwargs):
-        return self.v3_request(path, method='PATCH',
-                               expected_status=expected_status, **kwargs)
+    def patch(self, path, **kwargs):
+        r = self.v3_request(method='PATCH', path=path, **kwargs)
+        if 'expected_status' not in kwargs:
+            self.assertResponseStatus(r, 200)
+        return r
 
-    def delete(self, path, expected_status=http_client.NO_CONTENT, **kwargs):
-        return self.v3_request(path, method='DELETE',
-                               expected_status=expected_status, **kwargs)
+    def delete(self, path, **kwargs):
+        r = self.v3_request(method='DELETE', path=path, **kwargs)
+        if 'expected_status' not in kwargs:
+            self.assertResponseStatus(r, 204)
+        return r
 
     def assertValidErrorResponse(self, r):
         resp = r.result
index f22e9f2..6b15b1c 100644 (file)
@@ -363,13 +363,14 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
         # validates the returned token and it should be valid.
         self.head('/auth/tokens',
                   headers={'x-subject-token': subject_token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
         # now disable the domain
         self.domain['enabled'] = False
         url = "/domains/%(domain_id)s" % {'domain_id': self.domain['id']}
         self.patch(url,
-                   body={'domain': {'enabled': False}})
+                   body={'domain': {'enabled': False}},
+                   expected_status=200)
 
         # validates the same token again and it should be 'not found'
         # as the domain has already been disabled.
@@ -511,7 +512,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
         ref = self.new_project_ref(domain_id=self.domain_id, is_domain=True)
         self.post('/projects',
                   body={'project': ref},
-                  expected_status=http_client.NOT_IMPLEMENTED)
+                  expected_status=501)
 
     @utils.wip('waiting for projects acting as domains implementation')
     def test_create_project_without_parent_id_and_without_domain_id(self):
@@ -1289,9 +1290,9 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
         member_url = ('%(collection_url)s/%(role_id)s' % {
             'collection_url': collection_url,
             'role_id': self.role_id})
-        self.put(member_url)
+        self.put(member_url, expected_status=204)
         # Check the user has the role assigned
-        self.head(member_url)
+        self.head(member_url, expected_status=204)
         return member_url, user_ref
 
     def test_delete_user_before_removing_role_assignment_succeeds(self):
@@ -1300,7 +1301,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
         # Delete the user from identity backend
         self.identity_api.driver.delete_user(user['id'])
         # Clean up the role assignment
-        self.delete(member_url)
+        self.delete(member_url, expected_status=204)
         # Make sure the role is gone
         self.head(member_url, expected_status=http_client.NOT_FOUND)
 
@@ -1343,7 +1344,7 @@ class AssignmentTestCase(test_v3.RestfulTestCase,
         # validates the returned token; it should be valid.
         self.head('/auth/tokens',
                   headers={'x-subject-token': token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
         # revokes the grant from group on project.
         self.assignment_api.delete_grant(role_id=self.role['id'],
@@ -1868,7 +1869,7 @@ class RoleAssignmentBaseTestCase(test_v3.RestfulTestCase,
         self.default_user_id = self.user_ids[0]
         self.default_group_id = self.group_ids[0]
 
-    def get_role_assignments(self, expected_status=http_client.OK, **filters):
+    def get_role_assignments(self, expected_status=200, **filters):
         """Returns the result from querying role assignment API + queried URL.
 
         Calls GET /v3/role_assignments?<params> and returns its result, where
index 496a75c..d53a85d 100644 (file)
@@ -384,8 +384,9 @@ class TokenAPITests(object):
         v2_token = r.result['access']['token']['id']
 
         # Delete the v2 token using v3.
-        self.delete(
+        resp = self.delete(
             '/auth/tokens', headers={'X-Subject-Token': v2_token})
+        self.assertEqual(resp.status_code, 204)
 
         # Attempting to use the deleted token on v2 should fail.
         self.admin_request(
@@ -405,8 +406,7 @@ class TokenAPITests(object):
         self.assertEqual(expires, r.result['token']['expires_at'])
 
     def test_check_token(self):
-        self.head('/auth/tokens', headers=self.headers,
-                  expected_status=http_client.OK)
+        self.head('/auth/tokens', headers=self.headers, expected_status=200)
 
     def test_validate_token(self):
         r = self.get('/auth/tokens', headers=self.headers)
@@ -655,13 +655,11 @@ class TestTokenRevokeSelfAndAdmin(test_v3.RestfulTestCase):
                 password=self.userAdminA['password'],
                 domain_name=self.domainA['name']))
 
-        self.head('/auth/tokens', headers=headers,
-                  expected_status=http_client.OK,
+        self.head('/auth/tokens', headers=headers, expected_status=200,
                   token=adminA_token)
-        self.head('/auth/tokens', headers=headers,
-                  expected_status=http_client.OK,
+        self.head('/auth/tokens', headers=headers, expected_status=200,
                   token=user_token)
-        self.delete('/auth/tokens', headers=headers,
+        self.delete('/auth/tokens', headers=headers, expected_status=204,
                     token=user_token)
         # invalid X-Auth-Token and invalid X-Subject-Token
         self.head('/auth/tokens', headers=headers,
@@ -695,13 +693,11 @@ class TestTokenRevokeSelfAndAdmin(test_v3.RestfulTestCase):
                 password=self.userAdminA['password'],
                 domain_name=self.domainA['name']))
 
-        self.head('/auth/tokens', headers=headers,
-                  expected_status=http_client.OK,
+        self.head('/auth/tokens', headers=headers, expected_status=200,
                   token=adminA_token)
-        self.head('/auth/tokens', headers=headers,
-                  expected_status=http_client.OK,
+        self.head('/auth/tokens', headers=headers, expected_status=200,
                   token=user_token)
-        self.delete('/auth/tokens', headers=headers,
+        self.delete('/auth/tokens', headers=headers, expected_status=204,
                     token=adminA_token)
         # invalid X-Auth-Token and invalid X-Subject-Token
         self.head('/auth/tokens', headers=headers,
@@ -868,10 +864,10 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         # confirm both tokens are valid
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': unscoped_token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': scoped_token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
         # create a new role
         role = self.new_role_ref()
@@ -887,10 +883,10 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         # both tokens should remain valid
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': unscoped_token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': scoped_token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
     def test_deleting_user_grant_revokes_token(self):
         """Test deleting a user grant revokes token.
@@ -910,7 +906,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         # Confirm token is valid
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         # Delete the grant, which should invalidate the token
         grant_url = (
             '/projects/%(project_id)s/users/%(user_id)s/'
@@ -1012,19 +1008,19 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         # Confirm tokens are valid
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': tokenA},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': tokenB},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': tokenC},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': tokenD},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': tokenE},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
         # Delete the role, which should invalidate the tokens
         role_url = '/roles/%s' % self.role1['id']
@@ -1047,7 +1043,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         # ...but the one using role2 is still valid
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': tokenC},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
     def test_domain_user_role_assignment_maintains_token(self):
         """Test user-domain role assignment maintains existing token.
@@ -1067,7 +1063,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         # Confirm token is valid
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         # Assign a role, which should not affect the token
         grant_url = (
             '/domains/%(domain_id)s/users/%(user_id)s/'
@@ -1078,7 +1074,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         self.put(grant_url)
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
     def test_disabling_project_revokes_token(self):
         token = self.get_requested_token(
@@ -1090,7 +1086,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         # confirm token is valid
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
         # disable the project, which should invalidate the token
         self.patch(
@@ -1118,7 +1114,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         # confirm token is valid
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
         # delete the project, which should invalidate the token
         self.delete(
@@ -1167,13 +1163,13 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         # Confirm tokens are valid
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': token1},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': token2},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': token3},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         # Delete the group grant, which should invalidate the
         # tokens for user1 and user2
         grant_url = (
@@ -1213,7 +1209,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         # Confirm token is valid
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         # Delete the grant, which should invalidate the token
         grant_url = (
             '/domains/%(domain_id)s/groups/%(group_id)s/'
@@ -1224,7 +1220,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         self.put(grant_url)
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
     def test_group_membership_changes_revokes_token(self):
         """Test add/removal to/from group revokes token.
@@ -1254,10 +1250,10 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         # Confirm tokens are valid
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': token1},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': token2},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         # Remove user1 from group1, which should invalidate
         # the token
         self.delete('/groups/%(group_id)s/users/%(user_id)s' % {
@@ -1269,14 +1265,14 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         # But user2's token should still be valid
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': token2},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         # Adding user2 to a group should not invalidate token
         self.put('/groups/%(group_id)s/users/%(user_id)s' % {
             'group_id': self.group2['id'],
             'user_id': self.user2['id']})
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': token2},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
     def test_removing_role_assignment_does_not_affect_other_users(self):
         """Revoking a role from one user should not affect other users."""
@@ -1320,7 +1316,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         # authorization for the second user should still succeed
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': user3_token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         self.v3_authenticate_token(
             self.build_authentication_request(
                 user_id=self.user3['id'],
@@ -1370,7 +1366,8 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         token = self.get_v2_token()
 
         self.delete('/auth/tokens',
-                    headers={'X-Subject-Token': token})
+                    headers={'X-Subject-Token': token},
+                    expected_status=204)
 
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': token},
@@ -1400,7 +1397,8 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
 
         # revoke the project-scoped token.
         self.delete('/auth/tokens',
-                    headers={'X-Subject-Token': project_scoped_token})
+                    headers={'X-Subject-Token': project_scoped_token},
+                    expected_status=204)
 
         # The project-scoped token is invalidated.
         self.head('/auth/tokens',
@@ -1410,16 +1408,17 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         # The unscoped token should still be valid.
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': unscoped_token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
         # The domain-scoped token should still be valid.
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': domain_scoped_token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
         # revoke the domain-scoped token.
         self.delete('/auth/tokens',
-                    headers={'X-Subject-Token': domain_scoped_token})
+                    headers={'X-Subject-Token': domain_scoped_token},
+                    expected_status=204)
 
         # The domain-scoped token is invalid.
         self.head('/auth/tokens',
@@ -1429,7 +1428,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         # The unscoped token should still be valid.
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': unscoped_token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
     def test_revoke_token_from_token_v2(self):
         # Test that a scoped token can be requested from an unscoped token,
@@ -1447,7 +1446,8 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
 
         # revoke the project-scoped token.
         self.delete('/auth/tokens',
-                    headers={'X-Subject-Token': project_scoped_token})
+                    headers={'X-Subject-Token': project_scoped_token},
+                    expected_status=204)
 
         # The project-scoped token is invalidated.
         self.head('/auth/tokens',
@@ -1457,7 +1457,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
         # The unscoped token should still be valid.
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': unscoped_token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
 
 class TestTokenRevokeByAssignment(TestTokenRevokeById):
@@ -1501,7 +1501,7 @@ class TestTokenRevokeByAssignment(TestTokenRevokeById):
         # authorization for the projectA should still succeed
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': other_project_token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
         # while token for the projectB should not
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': project_token},
@@ -1563,24 +1563,27 @@ class TestTokenRevokeApi(TestTokenRevokeById):
     def test_revoke_token(self):
         scoped_token = self.get_scoped_token()
         headers = {'X-Subject-Token': scoped_token}
-        response = self.get('/auth/tokens', headers=headers).json_body['token']
+        response = self.get('/auth/tokens', headers=headers,
+                            expected_status=200).json_body['token']
 
-        self.delete('/auth/tokens', headers=headers)
+        self.delete('/auth/tokens', headers=headers, expected_status=204)
         self.head('/auth/tokens', headers=headers,
                   expected_status=http_client.NOT_FOUND)
-        events_response = self.get('/OS-REVOKE/events').json_body
+        events_response = self.get('/OS-REVOKE/events',
+                                   expected_status=200).json_body
         self.assertValidRevokedTokenResponse(events_response,
                                              audit_id=response['audit_ids'][0])
 
     def test_revoke_v2_token(self):
         token = self.get_v2_token()
         headers = {'X-Subject-Token': token}
-        response = self.get('/auth/tokens',
-                            headers=headers).json_body['token']
-        self.delete('/auth/tokens', headers=headers)
+        response = self.get('/auth/tokens', headers=headers,
+                            expected_status=200).json_body['token']
+        self.delete('/auth/tokens', headers=headers, expected_status=204)
         self.head('/auth/tokens', headers=headers,
                   expected_status=http_client.NOT_FOUND)
-        events_response = self.get('/OS-REVOKE/events').json_body
+        events_response = self.get('/OS-REVOKE/events',
+                                   expected_status=200).json_body
 
         self.assertValidRevokedTokenResponse(
             events_response,
@@ -1592,24 +1595,28 @@ class TestTokenRevokeApi(TestTokenRevokeById):
 
     def test_list_delete_project_shows_in_event_list(self):
         self.role_data_fixtures()
-        events = self.get('/OS-REVOKE/events').json_body['events']
+        events = self.get('/OS-REVOKE/events',
+                          expected_status=200).json_body['events']
         self.assertEqual([], events)
         self.delete(
             '/projects/%(project_id)s' % {'project_id': self.projectA['id']})
-        events_response = self.get('/OS-REVOKE/events').json_body
+        events_response = self.get('/OS-REVOKE/events',
+                                   expected_status=200).json_body
 
         self.assertValidDeletedProjectResponse(events_response,
                                                self.projectA['id'])
 
     def test_disable_domain_shows_in_event_list(self):
-        events = self.get('/OS-REVOKE/events').json_body['events']
+        events = self.get('/OS-REVOKE/events',
+                          expected_status=200).json_body['events']
         self.assertEqual([], events)
         disable_body = {'domain': {'enabled': False}}
         self.patch(
             '/domains/%(project_id)s' % {'project_id': self.domainA['id']},
             body=disable_body)
 
-        events = self.get('/OS-REVOKE/events').json_body
+        events = self.get('/OS-REVOKE/events',
+                          expected_status=200).json_body
 
         self.assertDomainInList(events, self.domainA['id'])
 
@@ -1639,7 +1646,8 @@ class TestTokenRevokeApi(TestTokenRevokeById):
 
     def test_list_delete_token_shows_in_event_list(self):
         self.role_data_fixtures()
-        events = self.get('/OS-REVOKE/events').json_body['events']
+        events = self.get('/OS-REVOKE/events',
+                          expected_status=200).json_body['events']
         self.assertEqual([], events)
 
         scoped_token = self.get_scoped_token()
@@ -1653,17 +1661,15 @@ class TestTokenRevokeApi(TestTokenRevokeById):
         response.json_body['token']
         headers3 = {'X-Subject-Token': response.headers['X-Subject-Token']}
 
-        self.head('/auth/tokens', headers=headers,
-                  expected_status=http_client.OK)
-        self.head('/auth/tokens', headers=headers2,
-                  expected_status=http_client.OK)
-        self.head('/auth/tokens', headers=headers3,
-                  expected_status=http_client.OK)
+        self.head('/auth/tokens', headers=headers, expected_status=200)
+        self.head('/auth/tokens', headers=headers2, expected_status=200)
+        self.head('/auth/tokens', headers=headers3, expected_status=200)
 
-        self.delete('/auth/tokens', headers=headers)
+        self.delete('/auth/tokens', headers=headers, expected_status=204)
         # NOTE(ayoung): not deleting token3, as it should be deleted
         # by previous
-        events_response = self.get('/OS-REVOKE/events').json_body
+        events_response = self.get('/OS-REVOKE/events',
+                                   expected_status=200).json_body
         events = events_response['events']
         self.assertEqual(1, len(events))
         self.assertEventDataInList(
@@ -1671,32 +1677,32 @@ class TestTokenRevokeApi(TestTokenRevokeById):
             audit_id=token2['audit_ids'][1])
         self.head('/auth/tokens', headers=headers,
                   expected_status=http_client.NOT_FOUND)
-        self.head('/auth/tokens', headers=headers2,
-                  expected_status=http_client.OK)
-        self.head('/auth/tokens', headers=headers3,
-                  expected_status=http_client.OK)
+        self.head('/auth/tokens', headers=headers2, expected_status=200)
+        self.head('/auth/tokens', headers=headers3, expected_status=200)
 
     def test_list_with_filter(self):
 
         self.role_data_fixtures()
-        events = self.get('/OS-REVOKE/events').json_body['events']
+        events = self.get('/OS-REVOKE/events',
+                          expected_status=200).json_body['events']
         self.assertEqual(0, len(events))
 
         scoped_token = self.get_scoped_token()
         headers = {'X-Subject-Token': scoped_token}
         auth = self.build_authentication_request(token=scoped_token)
         headers2 = {'X-Subject-Token': self.get_requested_token(auth)}
-        self.delete('/auth/tokens', headers=headers)
-        self.delete('/auth/tokens', headers=headers2)
+        self.delete('/auth/tokens', headers=headers, expected_status=204)
+        self.delete('/auth/tokens', headers=headers2, expected_status=204)
 
-        events = self.get('/OS-REVOKE/events').json_body['events']
+        events = self.get('/OS-REVOKE/events',
+                          expected_status=200).json_body['events']
 
         self.assertEqual(2, len(events))
         future = utils.isotime(timeutils.utcnow() +
                                datetime.timedelta(seconds=1000))
 
-        events = self.get('/OS-REVOKE/events?since=%s' % (future)
-                          ).json_body['events']
+        events = self.get('/OS-REVOKE/events?since=%s' % (future),
+                          expected_status=200).json_body['events']
         self.assertEqual(0, len(events))
 
 
@@ -3106,7 +3112,8 @@ class TestTrustChain(test_v3.RestfulTestCase):
     def test_delete_trust_cascade(self):
         self.assert_user_authenticate(self.user_chain[0])
         self.delete('/OS-TRUST/trusts/%(trust_id)s' % {
-            'trust_id': self.trust_chain[0]['id']})
+            'trust_id': self.trust_chain[0]['id']},
+            expected_status=204)
 
         headers = {'X-Subject-Token': self.last_token}
         self.head('/auth/tokens', headers=headers,
@@ -3116,10 +3123,12 @@ class TestTrustChain(test_v3.RestfulTestCase):
     def test_delete_broken_chain(self):
         self.assert_user_authenticate(self.user_chain[0])
         self.delete('/OS-TRUST/trusts/%(trust_id)s' % {
-            'trust_id': self.trust_chain[1]['id']})
+            'trust_id': self.trust_chain[1]['id']},
+            expected_status=204)
 
         self.delete('/OS-TRUST/trusts/%(trust_id)s' % {
-            'trust_id': self.trust_chain[0]['id']})
+            'trust_id': self.trust_chain[0]['id']},
+            expected_status=204)
 
     def test_trustor_roles_revoked(self):
         self.assert_user_authenticate(self.user_chain[0])
@@ -3214,7 +3223,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
         # make sure the trust exists
         trust = self.assertValidTrustResponse(r, ref)
         r = self.get(
-            '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']})
+            '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']},
+            expected_status=200)
         # get a token for the trustee
         auth_data = self.build_authentication_request(
             user_id=self.trustee_user['id'],
@@ -3232,7 +3242,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
         trust = self._initialize_test_consume_trust(2)
         # check decremented value
         r = self.get(
-            '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']})
+            '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']},
+            expected_status=200)
         trust = r.result.get('trust')
         self.assertIsNotNone(trust)
         self.assertEqual(1, trust['remaining_uses'])
@@ -3310,7 +3321,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
         trust = self.assertValidTrustResponse(r, ref)
 
         r = self.get(
-            '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']})
+            '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']},
+            expected_status=200)
         auth_data = self.build_authentication_request(
             user_id=self.trustee_user['id'],
             password=self.trustee_user['password'])
@@ -3321,7 +3333,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
             trust_id=trust['id'])
         r = self.v3_authenticate_token(auth_data)
         r = self.get(
-            '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']})
+            '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']},
+            expected_status=200)
         trust = r.result.get('trust')
         self.assertIsNone(trust['remaining_uses'])
 
@@ -3335,27 +3348,30 @@ class TestTrustAuth(test_v3.RestfulTestCase):
         trust = self.assertValidTrustResponse(r, ref)
 
         r = self.get(
-            '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']})
+            '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']},
+            expected_status=200)
         self.assertValidTrustResponse(r, ref)
 
         # validate roles on the trust
         r = self.get(
             '/OS-TRUST/trusts/%(trust_id)s/roles' % {
-                'trust_id': trust['id']})
+                'trust_id': trust['id']},
+            expected_status=200)
         roles = self.assertValidRoleListResponse(r, self.role)
         self.assertIn(self.role['id'], [x['id'] for x in roles])
         self.head(
             '/OS-TRUST/trusts/%(trust_id)s/roles/%(role_id)s' % {
                 'trust_id': trust['id'],
                 'role_id': self.role['id']},
-            expected_status=http_client.OK)
+            expected_status=200)
         r = self.get(
             '/OS-TRUST/trusts/%(trust_id)s/roles/%(role_id)s' % {
                 'trust_id': trust['id'],
-                'role_id': self.role['id']})
+                'role_id': self.role['id']},
+            expected_status=200)
         self.assertValidRoleResponse(r, self.role)
 
-        r = self.get('/OS-TRUST/trusts')
+        r = self.get('/OS-TRUST/trusts', expected_status=200)
         self.assertValidTrustListResponse(r, trust)
 
         # trusts are immutable
@@ -3365,7 +3381,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
             expected_status=http_client.NOT_FOUND)
 
         self.delete(
-            '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']})
+            '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']},
+            expected_status=204)
 
         self.get(
             '/OS-TRUST/trusts/%(trust_id)s' % {'trust_id': trust['id']},
@@ -3554,7 +3571,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
         path = '/v2.0/tokens/%s' % (token)
         self.admin_request(
             path=path, token=CONF.admin_token,
-            method='GET', expected_status=http_client.OK)
+            method='GET', expected_status=200)
 
     def test_exercise_trust_scoped_token_without_impersonation(self):
         ref = self.new_trust_ref(
@@ -3758,7 +3775,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
                                        expected_status=http_client.FORBIDDEN)
 
     def assertTrustTokensRevoked(self, trust_id):
-        revocation_response = self.get('/OS-REVOKE/events')
+        revocation_response = self.get('/OS-REVOKE/events',
+                                       expected_status=200)
         revocation_events = revocation_response.json_body['events']
         found = False
         for event in revocation_events:
@@ -3787,7 +3805,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
             r, self.trustee_user)
         trust_token = r.headers['X-Subject-Token']
         self.delete('/OS-TRUST/trusts/%(trust_id)s' % {
-            'trust_id': trust_id})
+            'trust_id': trust_id},
+            expected_status=204)
         headers = {'X-Subject-Token': trust_token}
         self.head('/auth/tokens', headers=headers,
                   expected_status=http_client.NOT_FOUND)
@@ -3814,7 +3833,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
             user_id=self.trustee_user['id'],
             password=self.trustee_user['password'],
             trust_id=trust['id'])
-        self.v3_authenticate_token(auth_data)
+        self.v3_authenticate_token(auth_data, expected_status=201)
 
         self.disable_user(self.user)
 
@@ -3842,7 +3861,7 @@ class TestTrustAuth(test_v3.RestfulTestCase):
             user_id=self.trustee_user['id'],
             password=self.trustee_user['password'],
             trust_id=trust['id'])
-        self.v3_authenticate_token(auth_data)
+        self.v3_authenticate_token(auth_data, expected_status=201)
 
         self.disable_user(self.trustee_user)
 
@@ -3867,7 +3886,8 @@ class TestTrustAuth(test_v3.RestfulTestCase):
         trust = self.assertValidTrustResponse(r, ref)
 
         self.delete('/OS-TRUST/trusts/%(trust_id)s' % {
-            'trust_id': trust['id']})
+            'trust_id': trust['id']},
+            expected_status=204)
 
         self.get('/OS-TRUST/trusts/%(trust_id)s' % {
             'trust_id': trust['id']},
@@ -3897,19 +3917,19 @@ class TestTrustAuth(test_v3.RestfulTestCase):
             r = self.post('/OS-TRUST/trusts', body={'trust': ref})
             self.assertValidTrustResponse(r, ref)
 
-        r = self.get('/OS-TRUST/trusts')
+        r = self.get('/OS-TRUST/trusts', expected_status=200)
         trusts = r.result['trusts']
         self.assertEqual(3, len(trusts))
         self.assertValidTrustListResponse(r)
 
         r = self.get('/OS-TRUST/trusts?trustor_user_id=%s' %
-                     self.user_id)
+                     self.user_id, expected_status=200)
         trusts = r.result['trusts']
         self.assertEqual(3, len(trusts))
         self.assertValidTrustListResponse(r)
 
         r = self.get('/OS-TRUST/trusts?trustee_user_id=%s' %
-                     self.user_id)
+                     self.user_id, expected_status=200)
         trusts = r.result['trusts']
         self.assertEqual(0, len(trusts))
 
@@ -3935,11 +3955,13 @@ class TestTrustAuth(test_v3.RestfulTestCase):
         trust_token = r.headers.get('X-Subject-Token')
 
         self.get('/OS-TRUST/trusts?trustor_user_id=%s' %
-                 self.user_id, token=trust_token)
+                 self.user_id, expected_status=200,
+                 token=trust_token)
 
         self.assertValidUserResponse(
             self.patch('/users/%s' % self.trustee_user['id'],
-                       body={'user': {'password': uuid.uuid4().hex}}))
+                       body={'user': {'password': uuid.uuid4().hex}},
+                       expected_status=200))
 
         self.get('/OS-TRUST/trusts?trustor_user_id=%s' %
                  self.user_id, expected_status=http_client.UNAUTHORIZED,
@@ -3971,13 +3993,14 @@ class TestTrustAuth(test_v3.RestfulTestCase):
                 'trust_id': trust['id'],
                 'role_id': self.role['id']},
             auth=auth_data,
-            expected_status=http_client.OK)
+            expected_status=200)
 
         r = self.get(
             '/OS-TRUST/trusts/%(trust_id)s/roles/%(role_id)s' % {
                 'trust_id': trust['id'],
                 'role_id': self.role['id']},
-            auth=auth_data)
+            auth=auth_data,
+            expected_status=200)
         self.assertValidRoleResponse(r, self.role)
 
     def test_do_not_consume_remaining_uses_when_get_token_fails(self):
@@ -4022,7 +4045,7 @@ class TestAPIProtectionWithoutAuthContextMiddleware(test_v3.RestfulTestCase):
                    'query_string': {},
                    'environment': {}}
         r = auth_controller.validate_token(context)
-        self.assertEqual(http_client.OK, r.status_code)
+        self.assertEqual(200, r.status_code)
 
 
 class TestAuthContext(unit.TestCase):
@@ -4082,7 +4105,9 @@ class TestAuthSpecificData(test_v3.RestfulTestCase):
 
     def test_get_catalog_project_scoped_token(self):
         """Call ``GET /auth/catalog`` with a project-scoped token."""
-        r = self.get('/auth/catalog')
+        r = self.get(
+            '/auth/catalog',
+            expected_status=200)
         self.assertValidCatalogResponse(r)
 
     def test_get_catalog_domain_scoped_token(self):
@@ -4116,7 +4141,7 @@ class TestAuthSpecificData(test_v3.RestfulTestCase):
             expected_status=http_client.UNAUTHORIZED)
 
     def test_get_projects_project_scoped_token(self):
-        r = self.get('/auth/projects')
+        r = self.get('/auth/projects', expected_status=200)
         self.assertThat(r.json['projects'], matchers.HasLength(1))
         self.assertValidProjectListResponse(r)
 
@@ -4124,7 +4149,7 @@ class TestAuthSpecificData(test_v3.RestfulTestCase):
         self.put(path='/domains/%s/users/%s/roles/%s' % (
             self.domain['id'], self.user['id'], self.role['id']))
 
-        r = self.get('/auth/domains')
+        r = self.get('/auth/domains', expected_status=200)
         self.assertThat(r.json['domains'], matchers.HasLength(1))
         self.assertValidDomainListResponse(r)
 
@@ -4135,7 +4160,7 @@ class TestFernetTokenProvider(test_v3.RestfulTestCase):
         self.useFixture(ksfixtures.KeyRepository(self.config_fixture))
 
     def _make_auth_request(self, auth_data):
-        resp = self.post('/auth/tokens', body=auth_data)
+        resp = self.post('/auth/tokens', body=auth_data, expected_status=201)
         token = resp.headers.get('X-Subject-Token')
         self.assertLess(len(token), 255)
         return token
@@ -4167,13 +4192,13 @@ class TestFernetTokenProvider(test_v3.RestfulTestCase):
             trust_id=trust['id'])
         return self._make_auth_request(auth_data)
 
-    def _validate_token(self, token, expected_status=http_client.OK):
+    def _validate_token(self, token, expected_status=200):
         return self.get(
             '/auth/tokens',
             headers={'X-Subject-Token': token},
             expected_status=expected_status)
 
-    def _revoke_token(self, token, expected_status=http_client.NO_CONTENT):
+    def _revoke_token(self, token, expected_status=204):
         return self.delete(
             '/auth/tokens',
             headers={'X-Subject-Token': token},
@@ -4547,8 +4572,7 @@ class TestAuthFernetTokenProvider(TestAuth):
         self.admin_app.extra_environ.update({'REMOTE_USER': remote_user,
                                              'AUTH_TYPE': 'Negotiate'})
         # Bind not current supported by Fernet, see bug 1433311.
-        self.v3_authenticate_token(auth_data,
-                                   expected_status=http_client.NOT_IMPLEMENTED)
+        self.v3_authenticate_token(auth_data, expected_status=501)
 
     def test_v2_v3_bind_token_intermix(self):
         self.config_fixture.config(group='token', bind='kerberos')
@@ -4563,7 +4587,7 @@ class TestAuthFernetTokenProvider(TestAuth):
         self.admin_request(path='/v2.0/tokens',
                            method='POST',
                            body=body,
-                           expected_status=http_client.NOT_IMPLEMENTED)
+                           expected_status=501)
 
     def test_auth_with_bind_token(self):
         self.config_fixture.config(group='token', bind=['kerberos'])
@@ -4573,5 +4597,4 @@ class TestAuthFernetTokenProvider(TestAuth):
         self.admin_app.extra_environ.update({'REMOTE_USER': remote_user,
                                              'AUTH_TYPE': 'Negotiate'})
         # Bind not current supported by Fernet, see bug 1433311.
-        self.v3_authenticate_token(auth_data,
-                                   expected_status=http_client.NOT_IMPLEMENTED)
+        self.v3_authenticate_token(auth_data, expected_status=501)
index 0d82390..c536169 100644 (file)
@@ -36,7 +36,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
         r = self.put(
             '/regions/%s' % region_id,
             body={'region': ref},
-            expected_status=http_client.CREATED)
+            expected_status=201)
         self.assertValidRegionResponse(r, ref)
         # Double-check that the region ID was kept as-is and not
         # populated with a UUID, as is the case with POST /v3/regions
@@ -49,7 +49,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
         r = self.put(
             '/regions/%s' % region_id,
             body={'region': ref},
-            expected_status=http_client.CREATED)
+            expected_status=201)
         self.assertValidRegionResponse(r, ref)
         # Double-check that the region ID was kept as-is and not
         # populated with a UUID, as is the case with POST /v3/regions
@@ -60,7 +60,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
         ref = dict(description="my region")
         self.put(
             '/regions/myregion',
-            body={'region': ref}, expected_status=http_client.CREATED)
+            body={'region': ref}, expected_status=201)
         # Create region again with duplicate id
         self.put(
             '/regions/myregion',
@@ -86,7 +86,9 @@ class CatalogTestCase(test_v3.RestfulTestCase):
         ref = self.new_region_ref()
         ref['id'] = ''
 
-        r = self.post('/regions', body={'region': ref})
+        r = self.post(
+            '/regions',
+            body={'region': ref}, expected_status=201)
         self.assertValidRegionResponse(r, ref)
         self.assertNotEmpty(r.result['region'].get('id'))
 
@@ -98,7 +100,10 @@ class CatalogTestCase(test_v3.RestfulTestCase):
         del ref['id']
 
         # let the service define the ID
-        r = self.post('/regions', body={'region': ref})
+        r = self.post(
+            '/regions',
+            body={'region': ref},
+            expected_status=201)
         self.assertValidRegionResponse(r, ref)
 
     def test_create_region_without_description(self):
@@ -107,7 +112,10 @@ class CatalogTestCase(test_v3.RestfulTestCase):
 
         del ref['description']
 
-        r = self.post('/regions', body={'region': ref})
+        r = self.post(
+            '/regions',
+            body={'region': ref},
+            expected_status=201)
         # Create the description in the reference to compare to since the
         # response should now have a description, even though we didn't send
         # it with the original reference.
@@ -127,10 +135,16 @@ class CatalogTestCase(test_v3.RestfulTestCase):
         ref1['description'] = region_desc
         ref2['description'] = region_desc
 
-        resp1 = self.post('/regions', body={'region': ref1})
+        resp1 = self.post(
+            '/regions',
+            body={'region': ref1},
+            expected_status=201)
         self.assertValidRegionResponse(resp1, ref1)
 
-        resp2 = self.post('/regions', body={'region': ref2})
+        resp2 = self.post(
+            '/regions',
+            body={'region': ref2},
+            expected_status=201)
         self.assertValidRegionResponse(resp2, ref2)
 
     def test_create_regions_without_descriptions(self):
@@ -145,9 +159,15 @@ class CatalogTestCase(test_v3.RestfulTestCase):
         del ref1['description']
         ref2['description'] = None
 
-        resp1 = self.post('/regions', body={'region': ref1})
+        resp1 = self.post(
+            '/regions',
+            body={'region': ref1},
+            expected_status=201)
 
-        resp2 = self.post('/regions', body={'region': ref2})
+        resp2 = self.post(
+            '/regions',
+            body={'region': ref2},
+            expected_status=201)
         # Create the descriptions in the references to compare to since the
         # responses should now have descriptions, even though we didn't send
         # a description with the original references.
@@ -211,14 +231,16 @@ class CatalogTestCase(test_v3.RestfulTestCase):
         """Call ``PATCH /regions/{region_id}``."""
         region_ref = self.new_region_ref()
 
-        resp = self.post('/regions', body={'region': region_ref})
+        resp = self.post('/regions', body={'region': region_ref},
+                         expected_status=201)
 
         region_updates = {
             # update with something that's not the description
             'parent_region_id': self.region_id,
         }
         resp = self.patch('/regions/%s' % region_ref['id'],
-                          body={'region': region_updates})
+                          body={'region': region_updates},
+                          expected_status=200)
 
         # NOTE(dstanek): Keystone should keep the original description.
         self.assertEqual(region_ref['description'],
@@ -591,7 +613,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
         ref = self.new_endpoint_ref(service_id=self.service_id)
         ref["region"] = uuid.uuid4().hex
         ref.pop('region_id')
-        self.post('/endpoints', body={'endpoint': ref})
+        self.post('/endpoints', body={'endpoint': ref}, expected_status=201)
         # Make sure the region is created
         self.get('/regions/%(region_id)s' % {
             'region_id': ref["region"]})
@@ -600,7 +622,7 @@ class CatalogTestCase(test_v3.RestfulTestCase):
         """EndpointV3 allows to creates the endpoint without region."""
         ref = self.new_endpoint_ref(service_id=self.service_id)
         ref.pop('region_id')
-        self.post('/endpoints', body={'endpoint': ref})
+        self.post('/endpoints', body={'endpoint': ref}, expected_status=201)
 
     def test_create_endpoint_with_empty_url(self):
         """Call ``POST /endpoints``."""
@@ -756,7 +778,9 @@ class CatalogTestCase(test_v3.RestfulTestCase):
 
         ref = self.new_endpoint_ref(self.service_id)
         ref['url'] = valid_url
-        self.post('/endpoints', body={'endpoint': ref})
+        self.post('/endpoints',
+                  body={'endpoint': ref},
+                  expected_status=201)
 
     def test_endpoint_create_with_invalid_url(self):
         """Test the invalid cases: substitutions is not exactly right.
index cf504b0..dd8cf2d 100644 (file)
@@ -382,7 +382,7 @@ class TestCredentialEc2(CredentialBaseTestCase):
         r = self.post(
             '/ec2tokens',
             body={'ec2Credentials': sig_ref},
-            expected_status=http_client.OK)
+            expected_status=200)
         self.assertValidTokenResponse(r)
 
     def test_ec2_credential_signature_validate(self):
index 3f7af87..701cd3c 100644 (file)
@@ -40,7 +40,7 @@ class DomainConfigTestCase(test_v3.RestfulTestCase):
         url = '/domains/%(domain_id)s/config' % {
             'domain_id': self.domain['id']}
         r = self.put(url, body={'config': self.config},
-                     expected_status=http_client.CREATED)
+                     expected_status=201)
         res = self.domain_config_api.get_config(self.domain['id'])
         self.assertEqual(self.config, r.result['config'])
         self.assertEqual(self.config, res)
@@ -50,11 +50,11 @@ class DomainConfigTestCase(test_v3.RestfulTestCase):
         self.put('/domains/%(domain_id)s/config' % {
             'domain_id': self.domain['id']},
             body={'config': self.config},
-            expected_status=http_client.CREATED)
+            expected_status=201)
         self.put('/domains/%(domain_id)s/config' % {
             'domain_id': self.domain['id']},
             body={'config': self.config},
-            expected_status=http_client.OK)
+            expected_status=200)
 
     def test_delete_config(self):
         """Call ``DELETE /domains{domain_id}/config``."""
@@ -80,7 +80,7 @@ class DomainConfigTestCase(test_v3.RestfulTestCase):
             'domain_id': self.domain['id']}
         r = self.get(url)
         self.assertEqual(self.config, r.result['config'])
-        self.head(url, expected_status=http_client.OK)
+        self.head(url, expected_status=200)
 
     def test_get_config_by_group(self):
         """Call ``GET & HEAD /domains{domain_id}/config/{group}``."""
@@ -89,7 +89,7 @@ class DomainConfigTestCase(test_v3.RestfulTestCase):
             'domain_id': self.domain['id']}
         r = self.get(url)
         self.assertEqual({'ldap': self.config['ldap']}, r.result['config'])
-        self.head(url, expected_status=http_client.OK)
+        self.head(url, expected_status=200)
 
     def test_get_config_by_option(self):
         """Call ``GET & HEAD /domains{domain_id}/config/{group}/{option}``."""
@@ -99,7 +99,7 @@ class DomainConfigTestCase(test_v3.RestfulTestCase):
         r = self.get(url)
         self.assertEqual({'url': self.config['ldap']['url']},
                          r.result['config'])
-        self.head(url, expected_status=http_client.OK)
+        self.head(url, expected_status=200)
 
     def test_get_non_existant_config(self):
         """Call ``GET /domains{domain_id}/config when no config defined``."""
index b0c8256..3423d2d 100644 (file)
@@ -53,14 +53,12 @@ class EndpointPolicyTestCase(test_v3.RestfulTestCase):
             url,
             expected_status=http_client.NOT_FOUND)
 
-        self.put(url)
+        self.put(url, expected_status=204)
 
         # test that the new resource is accessible.
-        self.assert_head_and_get_return_same_response(
-            url,
-            expected_status=http_client.NO_CONTENT)
+        self.assert_head_and_get_return_same_response(url, expected_status=204)
 
-        self.delete(url)
+        self.delete(url, expected_status=204)
 
         # test that the deleted resource is no longer accessible
         self.assert_head_and_get_return_same_response(
@@ -101,16 +99,18 @@ class EndpointPolicyTestCase(test_v3.RestfulTestCase):
         self.put('/policies/%(policy_id)s/OS-ENDPOINT-POLICY'
                  '/endpoints/%(endpoint_id)s' % {
                      'policy_id': self.policy['id'],
-                     'endpoint_id': self.endpoint['id']})
+                     'endpoint_id': self.endpoint['id']},
+                 expected_status=204)
 
         self.head('/endpoints/%(endpoint_id)s/OS-ENDPOINT-POLICY'
                   '/policy' % {
                       'endpoint_id': self.endpoint['id']},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
         r = self.get('/endpoints/%(endpoint_id)s/OS-ENDPOINT-POLICY'
                      '/policy' % {
-                         'endpoint_id': self.endpoint['id']})
+                         'endpoint_id': self.endpoint['id']},
+                     expected_status=200)
         self.assertValidPolicyResponse(r, ref=self.policy)
 
     def test_list_endpoints_for_policy(self):
@@ -119,11 +119,13 @@ class EndpointPolicyTestCase(test_v3.RestfulTestCase):
         self.put('/policies/%(policy_id)s/OS-ENDPOINT-POLICY'
                  '/endpoints/%(endpoint_id)s' % {
                      'policy_id': self.policy['id'],
-                     'endpoint_id': self.endpoint['id']})
+                     'endpoint_id': self.endpoint['id']},
+                 expected_status=204)
 
         r = self.get('/policies/%(policy_id)s/OS-ENDPOINT-POLICY'
                      '/endpoints' % {
-                         'policy_id': self.policy['id']})
+                         'policy_id': self.policy['id']},
+                     expected_status=200)
         self.assertValidEndpointListResponse(r, ref=self.endpoint)
         self.assertThat(r.result.get('endpoints'), matchers.HasLength(1))
 
@@ -133,8 +135,8 @@ class EndpointPolicyTestCase(test_v3.RestfulTestCase):
                    'policy_id': self.policy['id'],
                    'endpoint_id': self.endpoint['id']}
 
-        self.put(url)
-        self.head(url)
+        self.put(url, expected_status=204)
+        self.head(url, expected_status=204)
 
         self.delete('/endpoints/%(endpoint_id)s' % {
             'endpoint_id': self.endpoint['id']})
@@ -148,8 +150,8 @@ class EndpointPolicyTestCase(test_v3.RestfulTestCase):
                    'service_id': self.service['id'],
                    'region_id': self.region['id']}
 
-        self.put(url)
-        self.head(url)
+        self.put(url, expected_status=204)
+        self.head(url, expected_status=204)
 
         self.delete('/regions/%(region_id)s' % {
             'region_id': self.region['id']})
@@ -163,8 +165,8 @@ class EndpointPolicyTestCase(test_v3.RestfulTestCase):
                    'service_id': self.service['id'],
                    'region_id': self.region['id']}
 
-        self.put(url)
-        self.head(url)
+        self.put(url, expected_status=204)
+        self.head(url, expected_status=204)
 
         self.delete('/services/%(service_id)s' % {
             'service_id': self.service['id']})
@@ -177,8 +179,8 @@ class EndpointPolicyTestCase(test_v3.RestfulTestCase):
                    'policy_id': self.policy['id'],
                    'service_id': self.service['id']}
 
-        self.put(url)
-        self.get(url, expected_status=http_client.NO_CONTENT)
+        self.put(url, expected_status=204)
+        self.get(url, expected_status=204)
 
         self.delete('/policies/%(policy_id)s' % {
             'policy_id': self.policy['id']})
@@ -191,8 +193,8 @@ class EndpointPolicyTestCase(test_v3.RestfulTestCase):
                    'policy_id': self.policy['id'],
                    'service_id': self.service['id']}
 
-        self.put(url)
-        self.get(url, expected_status=http_client.NO_CONTENT)
+        self.put(url, expected_status=204)
+        self.get(url, expected_status=204)
 
         self.delete('/services/%(service_id)s' % {
             'service_id': self.service['id']})
index 5717e67..4d7dcaa 100644 (file)
@@ -815,7 +815,7 @@ class FederatedIdentityProviderTests(FederationTests):
         if body is None:
             body = self._http_idp_input()
         resp = self.put(url, body={'identity_provider': body},
-                        expected_status=http_client.CREATED)
+                        expected_status=201)
         return resp
 
     def _http_idp_input(self, **kwargs):
@@ -1027,7 +1027,7 @@ class FederatedIdentityProviderTests(FederationTests):
         url = self.base_url(suffix=uuid.uuid4().hex)
         body = self._http_idp_input()
         self.put(url, body={'identity_provider': body},
-                 expected_status=http_client.CREATED)
+                 expected_status=201)
         self.put(url, body={'identity_provider': body},
                  expected_status=http_client.CONFLICT)
 
@@ -1084,7 +1084,7 @@ class FederatedIdentityProviderTests(FederationTests):
         idp_url = self.base_url(suffix=idp_id)
 
         # assign protocol to IdP
-        kwargs = {'expected_status': http_client.CREATED}
+        kwargs = {'expected_status': 201}
         resp, idp_id, proto = self._assign_protocol_to_idp(
             url=url,
             idp_id=idp_id,
@@ -1179,7 +1179,7 @@ class FederatedIdentityProviderTests(FederationTests):
     def test_assign_protocol_to_idp(self):
         """Assign a protocol to existing IdP."""
 
-        self._assign_protocol_to_idp(expected_status=http_client.CREATED)
+        self._assign_protocol_to_idp(expected_status=201)
 
     def test_protocol_composite_pk(self):
         """Test whether Keystone let's add two entities with identical
@@ -1193,7 +1193,7 @@ class FederatedIdentityProviderTests(FederationTests):
         """
         url = self.base_url(suffix='%(idp_id)s/protocols/%(protocol_id)s')
 
-        kwargs = {'expected_status': http_client.CREATED}
+        kwargs = {'expected_status': 201}
         self._assign_protocol_to_idp(proto='saml2',
                                      url=url, **kwargs)
 
@@ -1209,7 +1209,7 @@ class FederatedIdentityProviderTests(FederationTests):
         """
         url = self.base_url(suffix='%(idp_id)s/protocols/%(protocol_id)s')
 
-        kwargs = {'expected_status': http_client.CREATED}
+        kwargs = {'expected_status': 201}
         resp, idp_id, proto = self._assign_protocol_to_idp(proto='saml2',
                                                            url=url, **kwargs)
         kwargs = {'expected_status': http_client.CONFLICT}
@@ -1235,8 +1235,7 @@ class FederatedIdentityProviderTests(FederationTests):
     def test_get_protocol(self):
         """Create and later fetch protocol tied to IdP."""
 
-        resp, idp_id, proto = self._assign_protocol_to_idp(
-            expected_status=http_client.CREATED)
+        resp, idp_id, proto = self._assign_protocol_to_idp(expected_status=201)
         proto_id = self._fetch_attribute_from_response(resp, 'protocol')['id']
         url = "%s/protocols/%s" % (idp_id, proto_id)
         url = self.base_url(suffix=url)
@@ -1255,14 +1254,12 @@ class FederatedIdentityProviderTests(FederationTests):
         Compare input and output id sets.
 
         """
-        resp, idp_id, proto = self._assign_protocol_to_idp(
-            expected_status=http_client.CREATED)
+        resp, idp_id, proto = self._assign_protocol_to_idp(expected_status=201)
         iterations = random.randint(0, 16)
         protocol_ids = []
         for _ in range(iterations):
-            resp, _, proto = self._assign_protocol_to_idp(
-                idp_id=idp_id,
-                expected_status=http_client.CREATED)
+            resp, _, proto = self._assign_protocol_to_idp(idp_id=idp_id,
+                                                          expected_status=201)
             proto_id = self._fetch_attribute_from_response(resp, 'protocol')
             proto_id = proto_id['id']
             protocol_ids.append(proto_id)
@@ -1281,8 +1278,7 @@ class FederatedIdentityProviderTests(FederationTests):
     def test_update_protocols_attribute(self):
         """Update protocol's attribute."""
 
-        resp, idp_id, proto = self._assign_protocol_to_idp(
-            expected_status=http_client.CREATED)
+        resp, idp_id, proto = self._assign_protocol_to_idp(expected_status=201)
         new_mapping_id = uuid.uuid4().hex
 
         url = "%s/protocols/%s" % (idp_id, proto)
@@ -1303,8 +1299,7 @@ class FederatedIdentityProviderTests(FederationTests):
         """
         url = self.base_url(suffix='/%(idp_id)s/'
                                    'protocols/%(protocol_id)s')
-        resp, idp_id, proto = self._assign_protocol_to_idp(
-            expected_status=http_client.CREATED)
+        resp, idp_id, proto = self._assign_protocol_to_idp(expected_status=201)
         url = url % {'idp_id': idp_id,
                      'protocol_id': proto}
         self.delete(url)
@@ -1345,7 +1340,7 @@ class MappingCRUDTests(FederationTests):
         url = self.MAPPING_URL + uuid.uuid4().hex
         resp = self.put(url,
                         body={'mapping': mapping_fixtures.MAPPING_LARGE},
-                        expected_status=http_client.CREATED)
+                        expected_status=201)
         return resp
 
     def _get_id_from_response(self, resp):
@@ -1362,7 +1357,7 @@ class MappingCRUDTests(FederationTests):
         resp = self.get(url)
         entities = resp.result.get('mappings')
         self.assertIsNotNone(entities)
-        self.assertResponseStatus(resp, http_client.OK)
+        self.assertResponseStatus(resp, 200)
         self.assertValidListLinks(resp.result.get('links'))
         self.assertEqual(1, len(entities))
 
@@ -1372,7 +1367,7 @@ class MappingCRUDTests(FederationTests):
         mapping_id = self._get_id_from_response(resp)
         url = url % {'mapping_id': str(mapping_id)}
         resp = self.delete(url)
-        self.assertResponseStatus(resp, http_client.NO_CONTENT)
+        self.assertResponseStatus(resp, 204)
         self.get(url, expected_status=http_client.NOT_FOUND)
 
     def test_mapping_get(self):
@@ -1976,8 +1971,7 @@ class FederatedTokenTests(FederationTests, FederatedSetupMixin):
             token_id, 'project',
             self.project_all['id'])
 
-        self.v3_authenticate_token(
-            scoped_token, expected_status=http_client.INTERNAL_SERVER_ERROR)
+        self.v3_authenticate_token(scoped_token, expected_status=500)
 
     def test_lists_with_missing_group_in_backend(self):
         """Test a mapping that points to a group that does not exist
@@ -2529,7 +2523,7 @@ class SAMLGenerationTests(FederationTests):
         self.sp = self.sp_ref()
         url = '/OS-FEDERATION/service_providers/' + self.SERVICE_PROVDIER_ID
         self.put(url, body={'service_provider': self.sp},
-                 expected_status=http_client.CREATED)
+                 expected_status=201)
 
     def test_samlize_token_values(self):
         """Test the SAML generator produces a SAML object.
@@ -2763,7 +2757,7 @@ class SAMLGenerationTests(FederationTests):
                                return_value=self.signed_assertion):
             http_response = self.post(self.SAML_GENERATION_ROUTE, body=body,
                                       response_content_type='text/xml',
-                                      expected_status=http_client.OK)
+                                      expected_status=200)
 
         response = etree.fromstring(http_response.result)
         issuer = response[0]
@@ -2879,7 +2873,7 @@ class SAMLGenerationTests(FederationTests):
                                return_value=self.signed_assertion):
             http_response = self.post(self.ECP_GENERATION_ROUTE, body=body,
                                       response_content_type='text/xml',
-                                      expected_status=http_client.OK)
+                                      expected_status=200)
 
         env_response = etree.fromstring(http_response.result)
         header = env_response[0]
@@ -3079,13 +3073,13 @@ class IdPMetadataGenerationTests(FederationTests):
                           self.generator.generate_metadata)
 
     def test_get_metadata_with_no_metadata_file_configured(self):
-        self.get(self.METADATA_URL,
-                 expected_status=http_client.INTERNAL_SERVER_ERROR)
+        self.get(self.METADATA_URL, expected_status=500)
 
     def test_get_metadata(self):
         self.config_fixture.config(
             group='saml', idp_metadata_path=XMLDIR + '/idp_saml2_metadata.xml')
-        r = self.get(self.METADATA_URL, response_content_type='text/xml')
+        r = self.get(self.METADATA_URL, response_content_type='text/xml',
+                     expected_status=200)
         self.assertEqual('text/xml', r.headers.get('Content-Type'))
 
         reference_file = _load_xml('idp_saml2_metadata.xml')
@@ -3108,7 +3102,7 @@ class ServiceProviderTests(FederationTests):
         self.SP_REF = self.sp_ref()
         self.SERVICE_PROVIDER = self.put(
             url, body={'service_provider': self.SP_REF},
-            expected_status=http_client.CREATED).result
+            expected_status=201).result
 
     def sp_ref(self):
         ref = {
@@ -3127,7 +3121,7 @@ class ServiceProviderTests(FederationTests):
 
     def test_get_service_provider(self):
         url = self.base_url(suffix=self.SERVICE_PROVIDER_ID)
-        resp = self.get(url)
+        resp = self.get(url, expected_status=200)
         self.assertValidEntity(resp.result['service_provider'],
                                keys_to_check=self.SP_KEYS)
 
@@ -3139,7 +3133,7 @@ class ServiceProviderTests(FederationTests):
         url = self.base_url(suffix=uuid.uuid4().hex)
         sp = self.sp_ref()
         resp = self.put(url, body={'service_provider': sp},
-                        expected_status=http_client.CREATED)
+                        expected_status=201)
         self.assertValidEntity(resp.result['service_provider'],
                                keys_to_check=self.SP_KEYS)
 
@@ -3149,7 +3143,7 @@ class ServiceProviderTests(FederationTests):
         sp = self.sp_ref()
         del sp['relay_state_prefix']
         resp = self.put(url, body={'service_provider': sp},
-                        expected_status=http_client.CREATED)
+                        expected_status=201)
         sp_result = resp.result['service_provider']
         self.assertEqual(CONF.saml.relay_state_prefix,
                          sp_result['relay_state_prefix'])
@@ -3161,7 +3155,7 @@ class ServiceProviderTests(FederationTests):
         non_default_prefix = uuid.uuid4().hex
         sp['relay_state_prefix'] = non_default_prefix
         resp = self.put(url, body={'service_provider': sp},
-                        expected_status=http_client.CREATED)
+                        expected_status=201)
         sp_result = resp.result['service_provider']
         self.assertEqual(non_default_prefix,
                          sp_result['relay_state_prefix'])
@@ -3188,8 +3182,7 @@ class ServiceProviderTests(FederationTests):
         }
         for id, sp in ref_service_providers.items():
             url = self.base_url(suffix=id)
-            self.put(url, body={'service_provider': sp},
-                     expected_status=http_client.CREATED)
+            self.put(url, body={'service_provider': sp}, expected_status=201)
 
         # Insert ids into service provider object, we will compare it with
         # responses from server and those include 'id' attribute.
@@ -3216,14 +3209,15 @@ class ServiceProviderTests(FederationTests):
         """
         new_sp_ref = self.sp_ref()
         url = self.base_url(suffix=self.SERVICE_PROVIDER_ID)
-        resp = self.patch(url, body={'service_provider': new_sp_ref})
+        resp = self.patch(url, body={'service_provider': new_sp_ref},
+                          expected_status=200)
         patch_result = resp.result
         new_sp_ref['id'] = self.SERVICE_PROVIDER_ID
         self.assertValidEntity(patch_result['service_provider'],
                                ref=new_sp_ref,
                                keys_to_check=self.SP_KEYS)
 
-        resp = self.get(url)
+        resp = self.get(url, expected_status=200)
         get_result = resp.result
 
         self.assertDictEqual(patch_result['service_provider'],
@@ -3261,14 +3255,15 @@ class ServiceProviderTests(FederationTests):
         non_default_prefix = uuid.uuid4().hex
         new_sp_ref['relay_state_prefix'] = non_default_prefix
         url = self.base_url(suffix=self.SERVICE_PROVIDER_ID)
-        resp = self.patch(url, body={'service_provider': new_sp_ref})
+        resp = self.patch(url, body={'service_provider': new_sp_ref},
+                          expected_status=200)
         sp_result = resp.result['service_provider']
         self.assertEqual(non_default_prefix,
                          sp_result['relay_state_prefix'])
 
     def test_delete_service_provider(self):
         url = self.base_url(suffix=self.SERVICE_PROVIDER_ID)
-        self.delete(url)
+        self.delete(url, expected_status=204)
 
     def test_delete_service_provider_404(self):
         url = self.base_url(suffix=uuid.uuid4().hex)
index 3d424ce..5a8e4fd 100644 (file)
@@ -295,17 +295,18 @@ class IdentityTestCase(test_v3.RestfulTestCase):
         old_password_auth = self.build_authentication_request(
             user_id=user_ref['id'],
             password=password)
-        r = self.v3_authenticate_token(old_password_auth)
+        r = self.v3_authenticate_token(old_password_auth, expected_status=201)
         old_token = r.headers.get('X-Subject-Token')
 
         # auth as user with a token should work before a password change
         old_token_auth = self.build_authentication_request(token=old_token)
-        self.v3_authenticate_token(old_token_auth)
+        self.v3_authenticate_token(old_token_auth, expected_status=201)
 
         # administrative password reset
         new_password = uuid.uuid4().hex
         self.patch('/users/%s' % user_ref['id'],
-                   body={'user': {'password': new_password}})
+                   body={'user': {'password': new_password}},
+                   expected_status=200)
 
         # auth as user with original password should not work after change
         self.v3_authenticate_token(old_password_auth,
@@ -319,7 +320,7 @@ class IdentityTestCase(test_v3.RestfulTestCase):
         new_password_auth = self.build_authentication_request(
             user_id=user_ref['id'],
             password=new_password)
-        self.v3_authenticate_token(new_password_auth)
+        self.v3_authenticate_token(new_password_auth, expected_status=201)
 
     def test_update_user_domain_id(self):
         """Call ``PATCH /users/{user_id}`` with domain_id."""
@@ -370,7 +371,7 @@ class IdentityTestCase(test_v3.RestfulTestCase):
         # Confirm token is valid for now
         self.head('/auth/tokens',
                   headers={'X-Subject-Token': token},
-                  expected_status=http_client.OK)
+                  expected_status=200)
 
         # Now delete the user
         self.delete('/users/%(user_id)s' % {
@@ -473,7 +474,8 @@ class IdentityTestCase(test_v3.RestfulTestCase):
         # administrative password reset
         new_password = uuid.uuid4().hex
         self.patch('/users/%s' % user_ref['id'],
-                   body={'user': {'password': new_password}})
+                   body={'user': {'password': new_password}},
+                   expected_status=200)
 
         self.assertNotIn(password, log_fix.output)
         self.assertNotIn(new_password, log_fix.output)
@@ -559,8 +561,7 @@ class UserSelfServiceChangingPasswordsTestCase(test_v3.RestfulTestCase):
         password = self.user_ref['password']
         self.user_ref = self.identity_api.create_user(self.user_ref)
         self.user_ref['password'] = password
-        self.token = self.get_request_token(self.user_ref['password'],
-                                            http_client.CREATED)
+        self.token = self.get_request_token(self.user_ref['password'], 201)
 
     def get_request_token(self, password, expected_status):
         auth_data = self.build_authentication_request(
@@ -580,16 +581,16 @@ class UserSelfServiceChangingPasswordsTestCase(test_v3.RestfulTestCase):
     def test_changing_password(self):
         # original password works
         token_id = self.get_request_token(self.user_ref['password'],
-                                          expected_status=http_client.CREATED)
+                                          expected_status=201)
         # original token works
         old_token_auth = self.build_authentication_request(token=token_id)
-        self.v3_authenticate_token(old_token_auth)
+        self.v3_authenticate_token(old_token_auth, expected_status=201)
 
         # change password
         new_password = uuid.uuid4().hex
         self.change_password(password=new_password,
                              original_password=self.user_ref['password'],
-                             expected_status=http_client.NO_CONTENT)
+                             expected_status=204)
 
         # old password fails
         self.get_request_token(self.user_ref['password'],
@@ -600,8 +601,7 @@ class UserSelfServiceChangingPasswordsTestCase(test_v3.RestfulTestCase):
                                    expected_status=http_client.NOT_FOUND)
 
         # new password works
-        self.get_request_token(new_password,
-                               expected_status=http_client.CREATED)
+        self.get_request_token(new_password, expected_status=201)
 
     def test_changing_password_with_missing_original_password_fails(self):
         r = self.change_password(password=uuid.uuid4().hex,
@@ -640,7 +640,7 @@ class UserSelfServiceChangingPasswordsTestCase(test_v3.RestfulTestCase):
         new_password = uuid.uuid4().hex
         self.change_password(password=new_password,
                              original_password=self.user_ref['password'],
-                             expected_status=http_client.NO_CONTENT)
+                             expected_status=204)
 
         self.assertNotIn(self.user_ref['password'], log_fix.output)
         self.assertNotIn(new_password, log_fix.output)
index 3a0d481..8794a42 100644 (file)
@@ -140,7 +140,7 @@ class ConsumerCRUDTests(OAuth1Tests):
         consumer = self._create_single_consumer()
         consumer_id = consumer['id']
         resp = self.delete(self.CONSUMER_URL + '/%s' % consumer_id)
-        self.assertResponseStatus(resp, http_client.NO_CONTENT)
+        self.assertResponseStatus(resp, 204)
 
     def test_consumer_get(self):
         consumer = self._create_single_consumer()
@@ -262,7 +262,7 @@ class OAuthFlowTests(OAuth1Tests):
 
         url = self._authorize_request_token(request_key)
         body = {'roles': [{'id': self.role_id}]}
-        resp = self.put(url, body=body, expected_status=http_client.OK)
+        resp = self.put(url, body=body, expected_status=200)
         self.verifier = resp.result['token']['oauth_verifier']
         self.assertTrue(all(i in core.VERIFIER_CHARS for i in self.verifier))
         self.assertEqual(8, len(self.verifier))
@@ -357,7 +357,7 @@ class AccessTokenCRUDTests(OAuthFlowTests):
         resp = self.delete('/users/%(user)s/OS-OAUTH1/access_tokens/%(auth)s'
                            % {'user': self.user_id,
                               'auth': self.access_token.key})
-        self.assertResponseStatus(resp, http_client.NO_CONTENT)
+        self.assertResponseStatus(resp, 204)
 
         # List access_token should be 0
         resp = self.get('/users/%(user_id)s/OS-OAUTH1/access_tokens'
@@ -400,7 +400,7 @@ class AuthTokenTests(OAuthFlowTests):
         resp = self.delete('/users/%(user)s/OS-OAUTH1/access_tokens/%(auth)s'
                            % {'user': self.user_id,
                               'auth': self.access_token.key})
-        self.assertResponseStatus(resp, http_client.NO_CONTENT)
+        self.assertResponseStatus(resp, 204)
 
         # Check Keystone Token no longer exists
         headers = {'X-Subject-Token': self.keystone_token_id,
@@ -415,7 +415,7 @@ class AuthTokenTests(OAuthFlowTests):
         consumer_id = self.consumer['key']
         resp = self.delete('/OS-OAUTH1/consumers/%(consumer_id)s'
                            % {'consumer_id': consumer_id})
-        self.assertResponseStatus(resp, http_client.NO_CONTENT)
+        self.assertResponseStatus(resp, 204)
 
         # List access_token should be 0
         resp = self.get('/users/%(user_id)s/OS-OAUTH1/access_tokens'
@@ -645,7 +645,7 @@ class MaliciousOAuth1Tests(OAuth1Tests):
 
         url = self._authorize_request_token(request_key)
         body = {'roles': [{'id': self.role_id}]}
-        resp = self.put(url, body=body, expected_status=http_client.OK)
+        resp = self.put(url, body=body, expected_status=200)
         verifier = resp.result['token']['oauth_verifier']
         self.assertIsNotNone(verifier)
 
@@ -719,7 +719,7 @@ class MaliciousOAuth1Tests(OAuth1Tests):
 
         url = self._authorize_request_token(request_key)
         body = {'roles': [{'id': self.role_id}]}
-        resp = self.put(url, body=body, expected_status=http_client.OK)
+        resp = self.put(url, body=body, expected_status=200)
         self.verifier = resp.result['token']['oauth_verifier']
 
         self.request_token.set_verifier(self.verifier)
@@ -753,8 +753,7 @@ class MaliciousOAuth1Tests(OAuth1Tests):
         # NOTE(stevemar): To simulate this error, we remove the Authorization
         # header from the post request.
         del headers['Authorization']
-        self.post(endpoint, headers=headers,
-                  expected_status=http_client.INTERNAL_SERVER_ERROR)
+        self.post(endpoint, headers=headers, expected_status=500)
 
 
 class OAuthNotificationTests(OAuth1Tests,
@@ -830,7 +829,7 @@ class OAuthNotificationTests(OAuth1Tests,
 
         url = self._authorize_request_token(request_key)
         body = {'roles': [{'id': self.role_id}]}
-        resp = self.put(url, body=body, expected_status=http_client.OK)
+        resp = self.put(url, body=body, expected_status=200)
         self.verifier = resp.result['token']['oauth_verifier']
         self.assertTrue(all(i in core.VERIFIER_CHARS for i in self.verifier))
         self.assertEqual(8, len(self.verifier))
@@ -859,7 +858,7 @@ class OAuthNotificationTests(OAuth1Tests,
         resp = self.delete('/users/%(user)s/OS-OAUTH1/access_tokens/%(auth)s'
                            % {'user': self.user_id,
                               'auth': self.access_token.key})
-        self.assertResponseStatus(resp, http_client.NO_CONTENT)
+        self.assertResponseStatus(resp, 204)
 
         # Test to ensure the delete access token notification is sent
         self._assert_notify_sent(access_key,
index 296e1d4..9922ae5 100644 (file)
@@ -461,8 +461,7 @@ class IdentityTestPolicySample(test_v3.RestfulTestCase):
         token = self.get_requested_token(auth)
 
         self.head('/auth/tokens', token=token,
-                  headers={'X-Subject-Token': token},
-                  expected_status=http_client.OK)
+                  headers={'X-Subject-Token': token}, expected_status=200)
 
     def test_user_check_user_token(self):
         # A user can check one of their own tokens.
@@ -475,8 +474,7 @@ class IdentityTestPolicySample(test_v3.RestfulTestCase):
         token2 = self.get_requested_token(auth)
 
         self.head('/auth/tokens', token=token1,
-                  headers={'X-Subject-Token': token2},
-                  expected_status=http_client.OK)
+                  headers={'X-Subject-Token': token2}, expected_status=200)
 
     def test_user_check_other_user_token_rejected(self):
         # A user cannot check another user's token.
@@ -512,8 +510,7 @@ class IdentityTestPolicySample(test_v3.RestfulTestCase):
         user_token = self.get_requested_token(user_auth)
 
         self.head('/auth/tokens', token=admin_token,
-                  headers={'X-Subject-Token': user_token},
-                  expected_status=http_client.OK)
+                  headers={'X-Subject-Token': user_token}, expected_status=200)
 
     def test_user_revoke_same_token(self):
         # Given a non-admin user token, the token can be used to revoke
@@ -686,8 +683,7 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
         # Return the expected return codes for APIs with and without data
         # with any specified status overriding the normal values
         if expected_status is None:
-            return (http_client.OK, http_client.CREATED,
-                    http_client.NO_CONTENT)
+            return (200, 201, 204)
         else:
             return (expected_status, expected_status, expected_status)
 
@@ -1054,7 +1050,7 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
             password=self.domain_admin_user['password'],
             domain_id=self.domainA['id'])
         entity_url = '/domains/%s' % self.domainA['id']
-        self.get(entity_url, auth=self.auth)
+        self.get(entity_url, auth=self.auth, expected_status=200)
 
     def test_list_user_credentials(self):
         self.credential_user = self.new_credential_ref(self.just_a_user['id'])
@@ -1186,8 +1182,7 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
         token = self.get_requested_token(auth)
 
         self.head('/auth/tokens', token=token,
-                  headers={'X-Subject-Token': token},
-                  expected_status=http_client.OK)
+                  headers={'X-Subject-Token': token}, expected_status=200)
 
     def test_user_check_user_token(self):
         # A user can check one of their own tokens.
@@ -1200,8 +1195,7 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
         token2 = self.get_requested_token(auth)
 
         self.head('/auth/tokens', token=token1,
-                  headers={'X-Subject-Token': token2},
-                  expected_status=http_client.OK)
+                  headers={'X-Subject-Token': token2}, expected_status=200)
 
     def test_user_check_other_user_token_rejected(self):
         # A user cannot check another user's token.
@@ -1237,8 +1231,7 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
         user_token = self.get_requested_token(user_auth)
 
         self.head('/auth/tokens', token=admin_token,
-                  headers={'X-Subject-Token': user_token},
-                  expected_status=http_client.OK)
+                  headers={'X-Subject-Token': user_token}, expected_status=200)
 
     def test_user_revoke_same_token(self):
         # Given a non-admin user token, the token can be used to revoke
index fc8051b..4081458 100644 (file)
@@ -751,7 +751,7 @@ class VersionTestCase(unit.TestCase):
     def test_public_version_v2(self):
         client = TestClient(self.public_app)
         resp = client.get('/v2.0/')
-        self.assertEqual(http_client.OK, resp.status_int)
+        self.assertEqual(200, resp.status_int)
         data = jsonutils.loads(resp.body)
         expected = v2_VERSION_RESPONSE
         self._paste_in_port(expected['version'],
@@ -762,7 +762,7 @@ class VersionTestCase(unit.TestCase):
     def test_admin_version_v2(self):
         client = TestClient(self.admin_app)
         resp = client.get('/v2.0/')
-        self.assertEqual(http_client.OK, resp.status_int)
+        self.assertEqual(200, resp.status_int)
         data = jsonutils.loads(resp.body)
         expected = v2_VERSION_RESPONSE
         self._paste_in_port(expected['version'],
@@ -775,7 +775,7 @@ class VersionTestCase(unit.TestCase):
         for app in (self.public_app, self.admin_app):
             client = TestClient(app)
             resp = client.get('/v2.0/')
-            self.assertEqual(http_client.OK, resp.status_int)
+            self.assertEqual(200, resp.status_int)
             data = jsonutils.loads(resp.body)
             expected = v2_VERSION_RESPONSE
             self._paste_in_port(expected['version'], 'http://localhost/v2.0/')
@@ -784,7 +784,7 @@ class VersionTestCase(unit.TestCase):
     def test_public_version_v3(self):
         client = TestClient(self.public_app)
         resp = client.get('/v3/')
-        self.assertEqual(http_client.OK, resp.status_int)
+        self.assertEqual(200, resp.status_int)
         data = jsonutils.loads(resp.body)
         expected = v3_VERSION_RESPONSE
         self._paste_in_port(expected['version'],
@@ -796,7 +796,7 @@ class VersionTestCase(unit.TestCase):
     def test_admin_version_v3(self):
         client = TestClient(self.admin_app)
         resp = client.get('/v3/')
-        self.assertEqual(http_client.OK, resp.status_int)
+        self.assertEqual(200, resp.status_int)
         data = jsonutils.loads(resp.body)
         expected = v3_VERSION_RESPONSE
         self._paste_in_port(expected['version'],
@@ -809,7 +809,7 @@ class VersionTestCase(unit.TestCase):
         for app in (self.public_app, self.admin_app):
             client = TestClient(app)
             resp = client.get('/v3/')
-            self.assertEqual(http_client.OK, resp.status_int)
+            self.assertEqual(200, resp.status_int)
             data = jsonutils.loads(resp.body)
             expected = v3_VERSION_RESPONSE
             self._paste_in_port(expected['version'], 'http://localhost/v3/')
@@ -824,7 +824,7 @@ class VersionTestCase(unit.TestCase):
 
         # request to /v3 should pass
         resp = client.get('/v3/')
-        self.assertEqual(http_client.OK, resp.status_int)
+        self.assertEqual(200, resp.status_int)
         data = jsonutils.loads(resp.body)
         expected = v3_VERSION_RESPONSE
         self._paste_in_port(expected['version'],
@@ -857,7 +857,7 @@ class VersionTestCase(unit.TestCase):
 
         # request to /v2.0 should pass
         resp = client.get('/v2.0/')
-        self.assertEqual(http_client.OK, resp.status_int)
+        self.assertEqual(200, resp.status_int)
         data = jsonutils.loads(resp.body)
         expected = v2_VERSION_RESPONSE
         self._paste_in_port(expected['version'],
index 2a5cb38..ed4c67d 100644 (file)
@@ -112,16 +112,15 @@ class ApplicationTest(BaseWSGITest):
 
         resp = wsgi.render_response(body=data)
         self.assertEqual('200 OK', resp.status)
-        self.assertEqual(http_client.OK, resp.status_int)
+        self.assertEqual(200, resp.status_int)
         self.assertEqual(body, resp.body)
         self.assertEqual('X-Auth-Token', resp.headers.get('Vary'))
         self.assertEqual(str(len(body)), resp.headers.get('Content-Length'))
 
     def test_render_response_custom_status(self):
-        resp = wsgi.render_response(
-            status=(http_client.NOT_IMPLEMENTED, 'Not Implemented'))
+        resp = wsgi.render_response(status=(501, 'Not Implemented'))
         self.assertEqual('501 Not Implemented', resp.status)
-        self.assertEqual(http_client.NOT_IMPLEMENTED, resp.status_int)
+        self.assertEqual(501, resp.status_int)
 
     def test_successful_require_attribute(self):
         app = FakeAttributeCheckerApp()
@@ -173,14 +172,14 @@ class ApplicationTest(BaseWSGITest):
     def test_render_response_no_body(self):
         resp = wsgi.render_response()
         self.assertEqual('204 No Content', resp.status)
-        self.assertEqual(http_client.NO_CONTENT, resp.status_int)
+        self.assertEqual(204, resp.status_int)
         self.assertEqual(b'', resp.body)
         self.assertEqual('0', resp.headers.get('Content-Length'))
         self.assertIsNone(resp.headers.get('Content-Type'))
 
     def test_render_response_head_with_body(self):
         resp = wsgi.render_response({'id': uuid.uuid4().hex}, method='HEAD')
-        self.assertEqual(http_client.OK, resp.status_int)
+        self.assertEqual(200, resp.status_int)
         self.assertEqual(b'', resp.body)
         self.assertNotEqual(resp.headers.get('Content-Length'), '0')
         self.assertEqual('application/json', resp.headers.get('Content-Type'))
index 5f74b43..bfb590d 100644 (file)
@@ -16,13 +16,17 @@ import hashlib
 import os
 import uuid
 
+import msgpack
 from oslo_utils import timeutils
+from six.moves import urllib
 
 from keystone.common import config
 from keystone.common import utils
+from keystone.contrib.federation import constants as federation_constants
 from keystone import exception
 from keystone.tests import unit
 from keystone.tests.unit import ksfixtures
+from keystone.tests.unit.ksfixtures import database
 from keystone.token import provider
 from keystone.token.providers import fernet
 from keystone.token.providers.fernet import token_formatters
@@ -57,7 +61,156 @@ class TestFernetTokenProvider(unit.TestCase):
             uuid.uuid4().hex)
 
 
+class TestValidate(unit.TestCase):
+    def setUp(self):
+        super(TestValidate, self).setUp()
+        self.useFixture(ksfixtures.KeyRepository(self.config_fixture))
+        self.useFixture(database.Database())
+        self.load_backends()
+
+    def config_overrides(self):
+        super(TestValidate, self).config_overrides()
+        self.config_fixture.config(group='token', provider='fernet')
+
+    def test_validate_v3_token_simple(self):
+        # Check the fields in the token result when use validate_v3_token
+        # with a simple token.
+
+        domain_ref = unit.new_domain_ref()
+        domain_ref = self.resource_api.create_domain(domain_ref['id'],
+                                                     domain_ref)
+
+        user_ref = unit.new_user_ref(domain_ref['id'])
+        user_ref = self.identity_api.create_user(user_ref)
+
+        method_names = ['password']
+        token_id, token_data_ = self.token_provider_api.issue_v3_token(
+            user_ref['id'], method_names)
+
+        token_data = self.token_provider_api.validate_v3_token(token_id)
+        token = token_data['token']
+        self.assertIsInstance(token['audit_ids'], list)
+        self.assertIsInstance(token['expires_at'], str)
+        self.assertEqual({}, token['extras'])
+        self.assertIsInstance(token['issued_at'], str)
+        self.assertEqual(method_names, token['methods'])
+        exp_user_info = {
+            'id': user_ref['id'],
+            'name': user_ref['name'],
+            'domain': {
+                'id': domain_ref['id'],
+                'name': domain_ref['name'],
+            },
+        }
+        self.assertEqual(exp_user_info, token['user'])
+
+    def test_validate_v3_token_federated_info(self):
+        # Check the user fields in the token result when use validate_v3_token
+        # when the token has federated info.
+
+        domain_ref = unit.new_domain_ref()
+        domain_ref = self.resource_api.create_domain(domain_ref['id'],
+                                                     domain_ref)
+
+        user_ref = unit.new_user_ref(domain_ref['id'])
+        user_ref = self.identity_api.create_user(user_ref)
+
+        method_names = ['mapped']
+
+        group_ids = [uuid.uuid4().hex, ]
+        identity_provider = uuid.uuid4().hex
+        protocol = uuid.uuid4().hex
+        auth_context = {
+            'user_id': user_ref['id'],
+            'group_ids': group_ids,
+            federation_constants.IDENTITY_PROVIDER: identity_provider,
+            federation_constants.PROTOCOL: protocol,
+        }
+        token_id, token_data_ = self.token_provider_api.issue_v3_token(
+            user_ref['id'], method_names, auth_context=auth_context)
+
+        token_data = self.token_provider_api.validate_v3_token(token_id)
+        token = token_data['token']
+        exp_user_info = {
+            'id': user_ref['id'],
+            'name': user_ref['id'],
+            'domain': {'id': CONF.federation.federated_domain_name,
+                       'name': CONF.federation.federated_domain_name, },
+            federation_constants.FEDERATION: {
+                'groups': [{'id': group_id} for group_id in group_ids],
+                'identity_provider': {'id': identity_provider, },
+                'protocol': {'id': protocol, },
+            },
+        }
+        self.assertEqual(exp_user_info, token['user'])
+
+    def test_validate_v3_token_trust(self):
+        # Check the trust fields in the token result when use validate_v3_token
+        # when the token has trust info.
+
+        domain_ref = unit.new_domain_ref()
+        domain_ref = self.resource_api.create_domain(domain_ref['id'],
+                                                     domain_ref)
+
+        user_ref = unit.new_user_ref(domain_ref['id'])
+        user_ref = self.identity_api.create_user(user_ref)
+
+        trustor_user_ref = unit.new_user_ref(domain_ref['id'])
+        trustor_user_ref = self.identity_api.create_user(trustor_user_ref)
+
+        project_ref = unit.new_project_ref(domain_id=domain_ref['id'])
+        project_ref = self.resource_api.create_project(project_ref['id'],
+                                                       project_ref)
+
+        role_ref = unit.new_role_ref()
+        role_ref = self.role_api.create_role(role_ref['id'], role_ref)
+
+        self.assignment_api.create_grant(
+            role_ref['id'], user_id=user_ref['id'],
+            project_id=project_ref['id'])
+
+        self.assignment_api.create_grant(
+            role_ref['id'], user_id=trustor_user_ref['id'],
+            project_id=project_ref['id'])
+
+        trustor_user_id = trustor_user_ref['id']
+        trustee_user_id = user_ref['id']
+        trust_ref = unit.new_trust_ref(
+            trustor_user_id, trustee_user_id, project_id=project_ref['id'],
+            role_ids=[role_ref['id'], ])
+        trust_ref = self.trust_api.create_trust(trust_ref['id'], trust_ref,
+                                                trust_ref['roles'])
+
+        method_names = ['password']
+
+        token_id, token_data_ = self.token_provider_api.issue_v3_token(
+            user_ref['id'], method_names, project_id=project_ref['id'],
+            trust=trust_ref)
+
+        token_data = self.token_provider_api.validate_v3_token(token_id)
+        token = token_data['token']
+        exp_trust_info = {
+            'id': trust_ref['id'],
+            'impersonation': False,
+            'trustee_user': {'id': user_ref['id'], },
+            'trustor_user': {'id': trustor_user_ref['id'], },
+        }
+        self.assertEqual(exp_trust_info, token['OS-TRUST:trust'])
+
+    def test_validate_v3_token_validation_error_exc(self):
+        # When the token format isn't recognized, TokenNotFound is raised.
+
+        # A uuid string isn't a valid fernet token.
+        token_id = uuid.uuid4().hex
+        self.assertRaises(exception.TokenNotFound,
+                          self.token_provider_api.validate_v3_token, token_id)
+
+
 class TestTokenFormatter(unit.TestCase):
+    def setUp(self):
+        super(TestTokenFormatter, self).setUp()
+        self.useFixture(ksfixtures.KeyRepository(self.config_fixture))
+
     def test_restore_padding(self):
         # 'a' will result in '==' padding, 'aa' will result in '=' padding, and
         # 'aaa' will result in no padding.
@@ -73,6 +226,39 @@ class TestTokenFormatter(unit.TestCase):
             )
             self.assertEqual(encoded_string, encoded_str_with_padding_restored)
 
+    def test_legacy_padding_validation(self):
+        first_value = uuid.uuid4().hex
+        second_value = uuid.uuid4().hex
+        payload = (first_value, second_value)
+        msgpack_payload = msgpack.packb(payload)
+
+        # NOTE(lbragstad): This method perserves the way that keystone used to
+        # percent encode the tokens, prior to bug #1491926.
+        def legacy_pack(payload):
+            tf = token_formatters.TokenFormatter()
+            encrypted_payload = tf.crypto.encrypt(payload)
+
+            # the encrypted_payload is returned with padding appended
+            self.assertTrue(encrypted_payload.endswith('='))
+
+            # using urllib.parse.quote will percent encode the padding, like
+            # keystone did in Kilo.
+            percent_encoded_payload = urllib.parse.quote(encrypted_payload)
+
+            # ensure that the padding was actaully percent encoded
+            self.assertTrue(percent_encoded_payload.endswith('%3D'))
+            return percent_encoded_payload
+
+        token_with_legacy_padding = legacy_pack(msgpack_payload)
+        tf = token_formatters.TokenFormatter()
+
+        # demonstrate the we can validate a payload that has been percent
+        # encoded with the Fernet logic that existed in Kilo
+        serialized_payload = tf.unpack(token_with_legacy_padding)
+        returned_payload = msgpack.unpackb(serialized_payload)
+        self.assertEqual(first_value, returned_payload[0])
+        self.assertEqual(second_value, returned_payload[1])
+
 
 class TestPayloads(unit.TestCase):
     def test_uuid_hex_to_byte_conversions(self):
@@ -204,8 +390,7 @@ class TestPayloads(unit.TestCase):
         self.assertEqual(exp_audit_ids, audit_ids)
         self.assertEqual(exp_trust_id, trust_id)
 
-    def test_unscoped_payload_with_non_uuid_user_id(self):
-        exp_user_id = 'someNonUuidUserId'
+    def _test_unscoped_payload_with_user_id(self, exp_user_id):
         exp_methods = ['password']
         exp_expires_at = utils.isotime(timeutils.utcnow(), subsecond=True)
         exp_audit_ids = [provider.random_urlsafe_str()]
@@ -221,30 +406,15 @@ class TestPayloads(unit.TestCase):
         self.assertEqual(exp_expires_at, expires_at)
         self.assertEqual(exp_audit_ids, audit_ids)
 
-    def test_project_scoped_payload_with_non_uuid_user_id(self):
-        exp_user_id = 'someNonUuidUserId'
-        exp_methods = ['password']
-        exp_project_id = uuid.uuid4().hex
-        exp_expires_at = utils.isotime(timeutils.utcnow(), subsecond=True)
-        exp_audit_ids = [provider.random_urlsafe_str()]
-
-        payload = token_formatters.ProjectScopedPayload.assemble(
-            exp_user_id, exp_methods, exp_project_id, exp_expires_at,
-            exp_audit_ids)
-
-        (user_id, methods, project_id, expires_at, audit_ids) = (
-            token_formatters.ProjectScopedPayload.disassemble(payload))
+    def test_unscoped_payload_with_non_uuid_user_id(self):
+        self._test_unscoped_payload_with_user_id('someNonUuidUserId')
 
-        self.assertEqual(exp_user_id, user_id)
-        self.assertEqual(exp_methods, methods)
-        self.assertEqual(exp_project_id, project_id)
-        self.assertEqual(exp_expires_at, expires_at)
-        self.assertEqual(exp_audit_ids, audit_ids)
+    def test_unscoped_payload_with_16_char_non_uuid_user_id(self):
+        self._test_unscoped_payload_with_user_id('0123456789abcdef')
 
-    def test_project_scoped_payload_with_non_uuid_project_id(self):
-        exp_user_id = uuid.uuid4().hex
+    def _test_project_scoped_payload_with_ids(self, exp_user_id,
+                                              exp_project_id):
         exp_methods = ['password']
-        exp_project_id = 'someNonUuidProjectId'
         exp_expires_at = utils.isotime(timeutils.utcnow(), subsecond=True)
         exp_audit_ids = [provider.random_urlsafe_str()]
 
@@ -261,8 +431,15 @@ class TestPayloads(unit.TestCase):
         self.assertEqual(exp_expires_at, expires_at)
         self.assertEqual(exp_audit_ids, audit_ids)
 
-    def test_domain_scoped_payload_with_non_uuid_user_id(self):
-        exp_user_id = 'someNonUuidUserId'
+    def test_project_scoped_payload_with_non_uuid_user_id(self):
+        self._test_project_scoped_payload_with_ids('someNonUuidUserId',
+                                                   'someNonUuidProjectId')
+
+    def test_project_scoped_payload_with_16_char_non_uuid_user_id(self):
+        self._test_project_scoped_payload_with_ids('0123456789abcdef',
+                                                   '0123456789abcdef')
+
+    def _test_domain_scoped_payload_with_user_id(self, exp_user_id):
         exp_methods = ['password']
         exp_domain_id = uuid.uuid4().hex
         exp_expires_at = utils.isotime(timeutils.utcnow(), subsecond=True)
@@ -281,32 +458,14 @@ class TestPayloads(unit.TestCase):
         self.assertEqual(exp_expires_at, expires_at)
         self.assertEqual(exp_audit_ids, audit_ids)
 
-    def test_trust_scoped_payload_with_non_uuid_user_id(self):
-        exp_user_id = 'someNonUuidUserId'
-        exp_methods = ['password']
-        exp_project_id = uuid.uuid4().hex
-        exp_expires_at = utils.isotime(timeutils.utcnow(), subsecond=True)
-        exp_audit_ids = [provider.random_urlsafe_str()]
-        exp_trust_id = uuid.uuid4().hex
-
-        payload = token_formatters.TrustScopedPayload.assemble(
-            exp_user_id, exp_methods, exp_project_id, exp_expires_at,
-            exp_audit_ids, exp_trust_id)
-
-        (user_id, methods, project_id, expires_at, audit_ids, trust_id) = (
-            token_formatters.TrustScopedPayload.disassemble(payload))
+    def test_domain_scoped_payload_with_non_uuid_user_id(self):
+        self._test_domain_scoped_payload_with_user_id('nonUuidUserId')
 
-        self.assertEqual(exp_user_id, user_id)
-        self.assertEqual(exp_methods, methods)
-        self.assertEqual(exp_project_id, project_id)
-        self.assertEqual(exp_expires_at, expires_at)
-        self.assertEqual(exp_audit_ids, audit_ids)
-        self.assertEqual(exp_trust_id, trust_id)
+    def test_domain_scoped_payload_with_16_char_non_uuid_user_id(self):
+        self._test_domain_scoped_payload_with_user_id('0123456789abcdef')
 
-    def test_trust_scoped_payload_with_non_uuid_project_id(self):
-        exp_user_id = uuid.uuid4().hex
+    def _test_trust_scoped_payload_with_ids(self, exp_user_id, exp_project_id):
         exp_methods = ['password']
-        exp_project_id = 'someNonUuidProjectId'
         exp_expires_at = utils.isotime(timeutils.utcnow(), subsecond=True)
         exp_audit_ids = [provider.random_urlsafe_str()]
         exp_trust_id = uuid.uuid4().hex
@@ -325,12 +484,19 @@ class TestPayloads(unit.TestCase):
         self.assertEqual(exp_audit_ids, audit_ids)
         self.assertEqual(exp_trust_id, trust_id)
 
-    def test_federated_payload_with_non_uuid_ids(self):
-        exp_user_id = 'someNonUuidUserId'
+    def test_trust_scoped_payload_with_non_uuid_user_id(self):
+        self._test_trust_scoped_payload_with_ids('someNonUuidUserId',
+                                                 'someNonUuidProjectId')
+
+    def test_trust_scoped_payload_with_16_char_non_uuid_user_id(self):
+        self._test_trust_scoped_payload_with_ids('0123456789abcdef',
+                                                 '0123456789abcdef')
+
+    def _test_federated_payload_with_ids(self, exp_user_id, exp_group_id):
         exp_methods = ['password']
         exp_expires_at = utils.isotime(timeutils.utcnow(), subsecond=True)
         exp_audit_ids = [provider.random_urlsafe_str()]
-        exp_federated_info = {'group_ids': [{'id': 'someNonUuidGroupId'}],
+        exp_federated_info = {'group_ids': [{'id': exp_group_id}],
                               'idp_id': uuid.uuid4().hex,
                               'protocol_id': uuid.uuid4().hex}
 
@@ -352,6 +518,14 @@ class TestPayloads(unit.TestCase):
         self.assertEqual(exp_federated_info['protocol_id'],
                          federated_info['protocol_id'])
 
+    def test_federated_payload_with_non_uuid_ids(self):
+        self._test_federated_payload_with_ids('someNonUuidUserId',
+                                              'someNonUuidGroupId')
+
+    def test_federated_payload_with_16_char_non_uuid_ids(self):
+        self._test_federated_payload_with_ids('0123456789abcdef',
+                                              '0123456789abcdef')
+
     def test_federated_project_scoped_payload(self):
         exp_user_id = 'someNonUuidUserId'
         exp_methods = ['token']
index 1bbacb0..a71c375 100644 (file)
@@ -167,7 +167,9 @@ class Provider(common.BaseProvider):
             'user': {
                 federation_constants.FEDERATION: federated_info,
                 'id': user_id,
-                'name': user_id
+                'name': user_id,
+                'domain': {'id': CONF.federation.federated_domain_name,
+                           'name': CONF.federation.federated_domain_name, },
             }
         }
 
index f0b6271..dbfee6d 100644 (file)
@@ -22,6 +22,7 @@ from oslo_log import log
 from oslo_utils import timeutils
 import six
 from six.moves import map
+from six.moves import urllib
 
 from keystone.auth import plugins as auth_plugins
 from keystone.common import utils as ks_utils
@@ -73,8 +74,19 @@ class TokenFormatter(object):
         """Unpack a token, and validate the payload."""
         token = six.binary_type(token)
 
-        # Restore padding on token before decoding it
-        token = TokenFormatter.restore_padding(token)
+        # TODO(lbragstad): Restore padding on token before decoding it.
+        # Initially in Kilo, Fernet tokens were returned to the user with
+        # padding appended to the token. Later in Liberty this padding was
+        # removed and restored in the Fernet provider. The following if
+        # statement ensures that we can validate tokens with and without token
+        # padding, in the event of an upgrade and the tokens that are issued
+        # throughout the upgrade. Remove this if statement when Mitaka opens
+        # for development and exclusively use the restore_padding() class
+        # method.
+        if token.endswith('%3D'):
+            token = urllib.parse.unquote(token)
+        else:
+            token = TokenFormatter.restore_padding(token)
 
         try:
             return self.crypto.decrypt(token)
@@ -338,15 +350,16 @@ class BasePayload(object):
         """Attempt to convert value to bytes or return value.
 
         :param value: value to attempt to convert to bytes
-        :returns: uuid value in bytes or value
+        :returns: tuple containing boolean indicating whether user_id was
+                  stored as bytes and uuid value as bytes or the original value
 
         """
         try:
-            return cls.convert_uuid_hex_to_bytes(value)
+            return (True, cls.convert_uuid_hex_to_bytes(value))
         except ValueError:
             # this might not be a UUID, depending on the situation (i.e.
             # federation)
-            return value
+            return (False, value)
 
     @classmethod
     def attempt_convert_uuid_bytes_to_hex(cls, value):
@@ -392,7 +405,9 @@ class UnscopedPayload(BasePayload):
                  audit_ids
 
         """
-        user_id = cls.attempt_convert_uuid_bytes_to_hex(payload[0])
+        (is_stored_as_bytes, user_id) = payload[0]
+        if is_stored_as_bytes:
+            user_id = cls.attempt_convert_uuid_bytes_to_hex(user_id)
         methods = auth_plugins.convert_integer_to_method_list(payload[1])
         expires_at_str = cls._convert_int_to_time_string(payload[2])
         audit_ids = list(map(provider.base64_encode, payload[3]))
@@ -438,7 +453,9 @@ class DomainScopedPayload(BasePayload):
                  expires_at_str, and audit_ids
 
         """
-        user_id = cls.attempt_convert_uuid_bytes_to_hex(payload[0])
+        (is_stored_as_bytes, user_id) = payload[0]
+        if is_stored_as_bytes:
+            user_id = cls.attempt_convert_uuid_bytes_to_hex(user_id)
         methods = auth_plugins.convert_integer_to_method_list(payload[1])
         try:
             domain_id = cls.convert_uuid_bytes_to_hex(payload[2])
@@ -486,9 +503,13 @@ class ProjectScopedPayload(BasePayload):
                  expires_at_str, and audit_ids
 
         """
-        user_id = cls.attempt_convert_uuid_bytes_to_hex(payload[0])
+        (is_stored_as_bytes, user_id) = payload[0]
+        if is_stored_as_bytes:
+            user_id = cls.attempt_convert_uuid_bytes_to_hex(user_id)
         methods = auth_plugins.convert_integer_to_method_list(payload[1])
-        project_id = cls.attempt_convert_uuid_bytes_to_hex(payload[2])
+        (is_stored_as_bytes, project_id) = payload[2]
+        if is_stored_as_bytes:
+            project_id = cls.attempt_convert_uuid_bytes_to_hex(project_id)
         expires_at_str = cls._convert_int_to_time_string(payload[3])
         audit_ids = list(map(provider.base64_encode, payload[4]))
 
@@ -532,9 +553,13 @@ class TrustScopedPayload(BasePayload):
                   expires_at_str, audit_ids, and trust_id
 
         """
-        user_id = cls.attempt_convert_uuid_bytes_to_hex(payload[0])
+        (is_stored_as_bytes, user_id) = payload[0]
+        if is_stored_as_bytes:
+            user_id = cls.attempt_convert_uuid_bytes_to_hex(user_id)
         methods = auth_plugins.convert_integer_to_method_list(payload[1])
-        project_id = cls.attempt_convert_uuid_bytes_to_hex(payload[2])
+        (is_stored_as_bytes, project_id) = payload[2]
+        if is_stored_as_bytes:
+            project_id = cls.attempt_convert_uuid_bytes_to_hex(project_id)
         expires_at_str = cls._convert_int_to_time_string(payload[3])
         audit_ids = list(map(provider.base64_encode, payload[4]))
         trust_id = cls.convert_uuid_bytes_to_hex(payload[5])
@@ -552,7 +577,9 @@ class FederatedUnscopedPayload(BasePayload):
 
     @classmethod
     def unpack_group_id(cls, group_id_in_bytes):
-        group_id = cls.attempt_convert_uuid_bytes_to_hex(group_id_in_bytes)
+        (is_stored_as_bytes, group_id) = group_id_in_bytes
+        if is_stored_as_bytes:
+            group_id = cls.attempt_convert_uuid_bytes_to_hex(group_id)
         return {'id': group_id}
 
     @classmethod
@@ -596,10 +623,14 @@ class FederatedUnscopedPayload(BasePayload):
 
         """
 
-        user_id = cls.attempt_convert_uuid_bytes_to_hex(payload[0])
+        (is_stored_as_bytes, user_id) = payload[0]
+        if is_stored_as_bytes:
+            user_id = cls.attempt_convert_uuid_bytes_to_hex(user_id)
         methods = auth_plugins.convert_integer_to_method_list(payload[1])
         group_ids = list(map(cls.unpack_group_id, payload[2]))
-        idp_id = cls.attempt_convert_uuid_bytes_to_hex(payload[3])
+        (is_stored_as_bytes, idp_id) = payload[3]
+        if is_stored_as_bytes:
+            idp_id = cls.attempt_convert_uuid_bytes_to_hex(idp_id)
         protocol_id = payload[4]
         expires_at_str = cls._convert_int_to_time_string(payload[5])
         audit_ids = list(map(provider.base64_encode, payload[6]))
@@ -653,11 +684,17 @@ class FederatedScopedPayload(FederatedUnscopedPayload):
                   group IDs
 
         """
-        user_id = cls.attempt_convert_uuid_bytes_to_hex(payload[0])
+        (is_stored_as_bytes, user_id) = payload[0]
+        if is_stored_as_bytes:
+            user_id = cls.attempt_convert_uuid_bytes_to_hex(user_id)
         methods = auth_plugins.convert_integer_to_method_list(payload[1])
-        scope_id = cls.attempt_convert_uuid_bytes_to_hex(payload[2])
+        (is_stored_as_bytes, scope_id) = payload[2]
+        if is_stored_as_bytes:
+            scope_id = cls.attempt_convert_uuid_bytes_to_hex(scope_id)
         group_ids = list(map(cls.unpack_group_id, payload[3]))
-        idp_id = cls.attempt_convert_uuid_bytes_to_hex(payload[4])
+        (is_stored_as_bytes, idp_id) = payload[4]
+        if is_stored_as_bytes:
+            idp_id = cls.attempt_convert_uuid_bytes_to_hex(idp_id)
         protocol_id = payload[5]
         expires_at_str = cls._convert_int_to_time_string(payload[6])
         audit_ids = list(map(provider.base64_encode, payload[7]))
diff --git a/keystone-moon/releasenotes/notes/.placeholder b/keystone-moon/releasenotes/notes/.placeholder
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/keystone-moon/releasenotes/notes/deprecations-c4afc19dc5324b9c.yaml b/keystone-moon/releasenotes/notes/deprecations-c4afc19dc5324b9c.yaml
new file mode 100644 (file)
index 0000000..0c1c4f1
--- /dev/null
@@ -0,0 +1,19 @@
+---
+other:
+  - Running keystone in eventlet remains deprecated and will be removed in the
+    Mitaka release.
+  - Using LDAP as the resource backend, i.e for projects and domains, is now
+    deprecated and will be removed in the Mitaka release.
+  - Using the full path to the driver class is deprecated in favor of using
+    the entrypoint. In the Mitaka release, the entrypoint must be used.
+  - In the [resource] and [role] sections of the ``keystone.conf`` file, not
+    specifying the driver and using the assignment driver is deprecated. In
+    the Mitaka release, the resource and role drivers will default to the SQL
+    driver.
+  - In ``keystone-paste.ini``, using ``paste.filter_factory`` is deprecated in
+    favor of the "use" directive, specifying an entrypoint.
+  - Not specifying a domain during a create user, group or project call, which
+    relied on falling back to the default domain, is now deprecated and will
+    be removed in the N release.
+  - Certain deprecated methods from the assignment manager were removed in
+    favor of the same methods in the [resource] and [role] manager.
diff --git a/keystone-moon/releasenotes/notes/new_features-e33d793d8a5ca76a.yaml b/keystone-moon/releasenotes/notes/new_features-e33d793d8a5ca76a.yaml
new file mode 100644 (file)
index 0000000..06e1db2
--- /dev/null
@@ -0,0 +1,21 @@
+---
+features:
+  - >
+    **Experimental** - Domain specific configuration options can be stored in
+    SQL instead of configuration files, using the new REST APIs.
+  - >
+    **Experimental** - Keystone now supports tokenless authorization with
+    X.509 SSL client certificate.
+  - Configuring per-Identity Provider WebSSO is now supported.
+  - >
+    ``openstack_user_domain`` and ``openstack_project_domain`` attributes were
+    added to SAML assertion in order to map user and project domains,
+    respectively.
+  - The credentials list call can now have its results filtered by credential
+    type.
+  - Support was improved for out-of-tree drivers by defining stable driver
+    interfaces.
+  - Several features were hardened, including Fernet tokens, federation,
+    domain specific configurations from database and role assignments.
+  - Certain variables in ``keystone.conf`` now have options, which determine
+    if the user's setting is valid.
diff --git a/keystone-moon/releasenotes/notes/upgrade_notes-ca81f5d531ab3522.yaml b/keystone-moon/releasenotes/notes/upgrade_notes-ca81f5d531ab3522.yaml
new file mode 100644 (file)
index 0000000..be8282c
--- /dev/null
@@ -0,0 +1,31 @@
+---
+upgrade:
+  - The EC2 token middleware, deprecated in Juno, is no longer available in
+    keystone. It has been moved to the keystonemiddleware package.
+  - The ``compute_port`` configuration option, deprecated in Juno, is no longer
+    available.
+  - The XML middleware stub has been removed, so references to it must be
+    removed from the ``keystone-paste.ini`` configuration file.
+  - stats_monitoring and stats_reporting paste filters have been removed, so
+    references to it must be removed from the ``keystone-paste.ini``
+    configuration file.
+  - The external authentication plugins ExternalDefault, ExternalDomain,
+    LegacyDefaultDomain, and LegacyDomain, deprecated in Icehouse, are no
+    longer available.
+  - The ``keystone.conf`` file now references entrypoint names for drivers.
+    For example, the drivers are now specified as "sql", "ldap", "uuid",
+    rather than the full module path. See the sample configuration file for
+    other examples.
+  - We now expose entrypoints for the ``keystone-manage`` command instead of a
+    file.
+  - Schema downgrades via ``keystone-manage db_sync`` are no longer supported.
+    Only upgrades are supported.
+  - Features that were "extensions" in previous releases (OAuth delegation,
+    Federated Identity support, Endpoint Policy, etc) are now enabled by
+    default.
+  - A new ``secure_proxy_ssl_header`` configuration option is available when
+    running keystone behind a proxy.
+  - Several configuration options have been deprecated, renamed, or moved to
+    new sections in the ``keystone.conf`` file.
+  - Domain name information can now be used in policy rules with the attribute
+    ``domain_name``.
diff --git a/keystone-moon/releasenotes/source/_static/.placeholder b/keystone-moon/releasenotes/source/_static/.placeholder
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/keystone-moon/releasenotes/source/_templates/.placeholder b/keystone-moon/releasenotes/source/_templates/.placeholder
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/keystone-moon/releasenotes/source/conf.py b/keystone-moon/releasenotes/source/conf.py
new file mode 100644 (file)
index 0000000..6df2e04
--- /dev/null
@@ -0,0 +1,275 @@
+# -*- coding: utf-8 -*-
+# 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 Release Notes documentation build configuration file, created by
+# sphinx-quickstart on Tue Nov  3 17:40:50 2015.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+# sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+    'oslosphinx',
+    'reno.sphinxext',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+# source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Keystone Release Notes'
+copyright = u'2015, Keystone Developers'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+import pbr.version
+keystone_version = pbr.version.VersionInfo('keystone')
+# The full version, including alpha/beta/rc tags.
+release = keystone_version.version_string_with_vcs()
+# The short X.Y version.
+version = keystone_version.canonical_version_string()
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+# language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+# today = ''
+# Else, today_fmt is used as the format for a strftime call.
+# today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = []
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+# default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+# add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+# add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+# show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+# modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+# keep_warnings = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# 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
+# documentation.
+# html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+# html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+# html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+# html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+# html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+# html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+# html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+# html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+# html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+# html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+# html_additional_pages = {}
+
+# If false, no module index is generated.
+# html_domain_indices = True
+
+# If false, no index is generated.
+# html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+# html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+# html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+# html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+# html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+# html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+# html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'KeystoneReleaseNotesdoc'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+    # The paper size ('letterpaper' or 'a4paper').
+    # 'papersize': 'letterpaper',
+
+    # The font size ('10pt', '11pt' or '12pt').
+    # 'pointsize': '10pt',
+
+    # Additional stuff for the LaTeX preamble.
+    # 'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+#  author, documentclass [howto, manual, or own class]).
+latex_documents = [
+    ('index', 'KeystoneReleaseNotes.tex',
+     u'Keystone Release Notes Documentation',
+     u'Keystone Developers', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+# latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+# latex_use_parts = False
+
+# If true, show page references after internal links.
+# latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+# latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+# latex_appendices = []
+
+# If false, no module index is generated.
+# latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'keystonereleasenotes', u'Keystone Release Notes Documentation',
+     [u'Keystone Developers'], 1)
+]
+
+# If true, show URL addresses after external links.
+# man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+    ('index', 'KeystoneReleaseNotes', u'Keystone Release Notes Documentation',
+     u'Keystone Developers', 'KeystoneReleaseNotes',
+     'Identity, Authentication and Access Management for OpenStack.',
+     'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+# texinfo_appendices = []
+
+# If false, no module index is generated.
+# texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+# texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+# texinfo_no_detailmenu = False
diff --git a/keystone-moon/releasenotes/source/index.rst b/keystone-moon/releasenotes/source/index.rst
new file mode 100644 (file)
index 0000000..9139d68
--- /dev/null
@@ -0,0 +1,9 @@
+========================
+ Keystone Release Notes
+========================
+
+.. toctree::
+   :maxdepth: 1
+
+   liberty
+   unreleased
diff --git a/keystone-moon/releasenotes/source/liberty.rst b/keystone-moon/releasenotes/source/liberty.rst
new file mode 100644 (file)
index 0000000..36217be
--- /dev/null
@@ -0,0 +1,6 @@
+==============================
+ Liberty Series Release Notes
+==============================
+
+.. release-notes::
+   :branch: origin/stable/liberty
diff --git a/keystone-moon/releasenotes/source/unreleased.rst b/keystone-moon/releasenotes/source/unreleased.rst
new file mode 100644 (file)
index 0000000..cd22aab
--- /dev/null
@@ -0,0 +1,5 @@
+==============================
+ Current Series Release Notes
+==============================
+
+.. release-notes::
index 555a148..8bc177b 100644 (file)
@@ -16,12 +16,12 @@ SQLAlchemy<1.1.0,>=0.9.9
 sqlalchemy-migrate>=0.9.6
 stevedore>=1.5.0 # Apache-2.0
 passlib>=1.6
-python-keystoneclient>=1.6.0
-keystonemiddleware>=2.0.0
+python-keystoneclient!=1.8.0,>=1.6.0
+keystonemiddleware!=2.4.0,>=2.0.0
 oslo.concurrency>=2.3.0 # Apache-2.0
 oslo.config>=2.3.0 # Apache-2.0
 oslo.context>=0.2.0 # Apache-2.0
-oslo.messaging!=1.17.0,!=1.17.1,>=1.16.0 # Apache-2.0
+oslo.messaging!=1.17.0,!=1.17.1,!=2.6.0,!=2.6.1,!=2.7.0,!=2.8.0,!=2.8.1,!=2.9.0,>=1.16.0 # Apache-2.0
 oslo.db>=2.4.1 # Apache-2.0
 oslo.i18n>=1.5.0 # Apache-2.0
 oslo.log>=1.8.0 # Apache-2.0
@@ -29,7 +29,7 @@ oslo.middleware>=2.8.0 # Apache-2.0
 oslo.policy>=0.5.0 # Apache-2.0
 oslo.serialization>=1.4.0 # Apache-2.0
 oslo.service>=0.7.0 # Apache-2.0
-oslo.utils>=2.0.0 # Apache-2.0
+oslo.utils!=2.6.0,>=2.0.0 # Apache-2.0
 oauthlib>=0.6
 pysaml2>=2.4.0
 dogpile.cache>=0.5.4
index c40aa3b..7788537 100644 (file)
@@ -1,6 +1,5 @@
 [metadata]
 name = keystone
-version = 9.0.0
 summary = OpenStack Identity
 description-file =
     README.rst
@@ -171,18 +170,6 @@ keystone.revoke =
     kvs = keystone.contrib.revoke.backends.kvs:Revoke
     sql = keystone.contrib.revoke.backends.sql:Revoke
 
-keystone.moon.configuration =
-    ram = keystone.contrib.moon.backends.memory:ConfigurationConnector
-
-keystone.moon.intraextension =
-    sql = keystone.contrib.moon.backends.sql:IntraExtensionConnector
-
-keystone.moon.log =
-    flat = keystone.contrib.moon.backends.flat:LogConnector
-
-keystone.moon.tenant =
-    sql = keystone.contrib.moon.backends.sql:TenantConnector
-
 oslo.config.opts =
     keystone = keystone.common.config:list_opts
     keystone.notifications = keystone.notifications:list_opts
@@ -196,7 +183,6 @@ paste.filter_factory =
     ec2_extension = keystone.contrib.ec2:Ec2Extension.factory
     ec2_extension_v3 = keystone.contrib.ec2:Ec2ExtensionV3.factory
     federation_extension = keystone.contrib.federation.routers:FederationExtension.factory
-    moon_extension = keystone.contrib.moon.routers:Routers.factory
     json_body = keystone.middleware:JsonBodyMiddleware.factory
     oauth1_extension = keystone.contrib.oauth1.routers:OAuth1Extension.factory
     request_id = oslo_middleware:RequestId.factory
index a027613..f10b992 100644 (file)
@@ -29,8 +29,9 @@ testtools>=1.4.0
 
 # For documentation
 oslosphinx>=2.5.0 # Apache-2.0
+reno>=0.1.1 # Apache2
 
 tempest-lib>=0.8.0
 
 # Functional tests.
-requests>=2.5.2
+requests!=2.8.0,>=2.5.2
index 0d24910..af1d9b8 100644 (file)
@@ -1,7 +1,7 @@
 [tox]
 minversion = 1.6
 skipsdist = True
-envlist = py27,py34,pep8,docs,genconfig
+envlist = py27,py34,pep8,docs,genconfig,releasenotes
 
 [testenv]
 usedevelop = True
@@ -97,6 +97,9 @@ commands=
     bash -c "rm -rf doc/source/api"
     python setup.py build_sphinx
 
+[testenv:releasenotes]
+commands = sphinx-build -a -E -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
+
 [testenv:genconfig]
 commands = oslo-config-generator --config-file=config-generator/keystone.conf