)]}'
{"keystone/exception.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"281775d56fc26906040dea7c5dfeb575592cc48c","unresolved":false,"context_lines":[{"line_number":358,"context_line":"    message_format \u003d _(\"Invalid resource limit: %(reason)s.\")"},{"line_number":359,"context_line":""},{"line_number":360,"context_line":""},{"line_number":361,"context_line":"class LimitTreeExceedError(Error):"},{"line_number":362,"context_line":"    message_format \u003d _(\"The process can\u0027t start for the reason that the \""},{"line_number":363,"context_line":"                       \"projects hierarchical depth in current deployment \""},{"line_number":364,"context_line":"                       \"exceed the enforcement model\u0027s limit. Please turn \""}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_b711d6b1","line":361,"range":{"start_line":361,"start_character":27,"end_line":361,"end_character":32},"updated":"2018-07-06 00:05:09.000000000","message":"This is probably not an error we send out via HTTP, suggest basing on Exception and raising at keystone \"startup\".","commit_id":"27a45216b115c3681d9bd44b50491fee8fd4e26a"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"92b997e51ba9b91447d481ba73a8865b2df61e30","unresolved":false,"context_lines":[{"line_number":358,"context_line":"    message_format \u003d _(\"Invalid resource limit: %(reason)s.\")"},{"line_number":359,"context_line":""},{"line_number":360,"context_line":""},{"line_number":361,"context_line":"class LimitTreeExceedError(Error):"},{"line_number":362,"context_line":"    message_format \u003d _(\"The process can\u0027t start for the reason that the \""},{"line_number":363,"context_line":"                       \"projects hierarchical depth in current deployment \""},{"line_number":364,"context_line":"                       \"exceed the enforcement model\u0027s limit. Please turn \""}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_5a9d0755","line":361,"range":{"start_line":361,"start_character":27,"end_line":361,"end_character":32},"in_reply_to":"5f7c97a3_b711d6b1","updated":"2018-07-06 07:01:19.000000000","message":"Done","commit_id":"27a45216b115c3681d9bd44b50491fee8fd4e26a"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"281775d56fc26906040dea7c5dfeb575592cc48c","unresolved":false,"context_lines":[{"line_number":359,"context_line":""},{"line_number":360,"context_line":""},{"line_number":361,"context_line":"class LimitTreeExceedError(Error):"},{"line_number":362,"context_line":"    message_format \u003d _(\"The process can\u0027t start for the reason that the \""},{"line_number":363,"context_line":"                       \"projects hierarchical depth in current deployment \""},{"line_number":364,"context_line":"                       \"exceed the enforcement model\u0027s limit. Please turn \""},{"line_number":365,"context_line":"                       \"the enforcement model back to the previous one and \""},{"line_number":366,"context_line":"                       \"fix the problem\")"},{"line_number":367,"context_line":"    code \u003d int(http_client.SERVICE_UNAVAILABLE)"},{"line_number":368,"context_line":"    title \u003d http_client.responses[http_client.SERVICE_UNAVAILABLE]"},{"line_number":369,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_5739623c","line":366,"range":{"start_line":362,"start_character":24,"end_line":366,"end_character":39},"updated":"2018-07-06 00:05:09.000000000","message":"Suggest:\n\n\"Keystone cannot start due to project hierarchical depth in the current deployment `%(max_depth_found)s` (project_id: %(project_id)s) exceeds the enforcement model\u0027s maximum limit of %(max_limit_depth)s. Please use a different enforcement model to correct the issue\".\n\nWe need to provide information where the depth was too much, what the max depth found was, and what the enforcement model\u0027s max depth is.","commit_id":"27a45216b115c3681d9bd44b50491fee8fd4e26a"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"92b997e51ba9b91447d481ba73a8865b2df61e30","unresolved":false,"context_lines":[{"line_number":359,"context_line":""},{"line_number":360,"context_line":""},{"line_number":361,"context_line":"class LimitTreeExceedError(Error):"},{"line_number":362,"context_line":"    message_format \u003d _(\"The process can\u0027t start for the reason that the \""},{"line_number":363,"context_line":"                       \"projects hierarchical depth in current deployment \""},{"line_number":364,"context_line":"                       \"exceed the enforcement model\u0027s limit. Please turn \""},{"line_number":365,"context_line":"                       \"the enforcement model back to the previous one and \""},{"line_number":366,"context_line":"                       \"fix the problem\")"},{"line_number":367,"context_line":"    code \u003d int(http_client.SERVICE_UNAVAILABLE)"},{"line_number":368,"context_line":"    title \u003d http_client.responses[http_client.SERVICE_UNAVAILABLE]"},{"line_number":369,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_1aa30f9d","line":366,"range":{"start_line":362,"start_character":24,"end_line":366,"end_character":39},"in_reply_to":"5f7c97a3_5739623c","updated":"2018-07-06 07:01:19.000000000","message":"sure, It\u0027s more clear.\n\nSince we only check the \"max_depth+1\" level in db, the max_depth_found can\u0027t be got.\nfor example, if the projects in db is like:\n\nfive level\nA - B - C - D - E\n\nthen for strict-two-level case, we only need to check if three level (A - B - C) exist. So here we can only know C exceed two level, but we don\u0027t know whether D or E is behind it. Get the max depth in db will cast more time which is unnecessary.","commit_id":"27a45216b115c3681d9bd44b50491fee8fd4e26a"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"281775d56fc26906040dea7c5dfeb575592cc48c","unresolved":false,"context_lines":[{"line_number":364,"context_line":"                       \"exceed the enforcement model\u0027s limit. Please turn \""},{"line_number":365,"context_line":"                       \"the enforcement model back to the previous one and \""},{"line_number":366,"context_line":"                       \"fix the problem\")"},{"line_number":367,"context_line":"    code \u003d int(http_client.SERVICE_UNAVAILABLE)"},{"line_number":368,"context_line":"    title \u003d http_client.responses[http_client.SERVICE_UNAVAILABLE]"},{"line_number":369,"context_line":""},{"line_number":370,"context_line":""},{"line_number":371,"context_line":"class NotFound(Error):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_7707be71","line":368,"range":{"start_line":367,"start_character":0,"end_line":368,"end_character":66},"updated":"2018-07-06 00:05:09.000000000","message":"See above comment re Error as the baseclass.","commit_id":"27a45216b115c3681d9bd44b50491fee8fd4e26a"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"92b997e51ba9b91447d481ba73a8865b2df61e30","unresolved":false,"context_lines":[{"line_number":364,"context_line":"                       \"exceed the enforcement model\u0027s limit. Please turn \""},{"line_number":365,"context_line":"                       \"the enforcement model back to the previous one and \""},{"line_number":366,"context_line":"                       \"fix the problem\")"},{"line_number":367,"context_line":"    code \u003d int(http_client.SERVICE_UNAVAILABLE)"},{"line_number":368,"context_line":"    title \u003d http_client.responses[http_client.SERVICE_UNAVAILABLE]"},{"line_number":369,"context_line":""},{"line_number":370,"context_line":""},{"line_number":371,"context_line":"class NotFound(Error):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_bab53bd2","line":368,"range":{"start_line":367,"start_character":0,"end_line":368,"end_character":66},"in_reply_to":"5f7c97a3_7707be71","updated":"2018-07-06 07:01:19.000000000","message":"Done","commit_id":"27a45216b115c3681d9bd44b50491fee8fd4e26a"}],"keystone/limit/core.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"bc965127158d1ae0d28404567a533f58f9b6384f","unresolved":false,"context_lines":[{"line_number":40,"context_line":"            CONF.unified_limit.enforcement_model)"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def check_project_depth(self):"},{"line_number":43,"context_line":"        \"\"\"Check project depth if satisfy current enforcement model or not.\"\"\""},{"line_number":44,"context_line":"        PROVIDERS.resource_api.check_project_depth("},{"line_number":45,"context_line":"            self.enforcement_model.MAX_PROJECT_TREE_DEPTH)"},{"line_number":46,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"5f7c97a3_fbf9f581","line":43,"range":{"start_line":43,"start_character":11,"end_line":43,"end_character":41},"updated":"2018-07-24 14:30:41.000000000","message":"Nit:\n\n  Check if project depth satisfies the current enforcement model.\n\nbut we can fix that in a follow up if we want.","commit_id":"8e44aa3b97e1892b0648177d1cb5836cfe5795e7"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"ac00d57aa51fb2fafde53758af94d59a193aae85","unresolved":false,"context_lines":[{"line_number":40,"context_line":"            CONF.unified_limit.enforcement_model)"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def check_project_depth(self):"},{"line_number":43,"context_line":"        \"\"\"Check project depth if satisfy current enforcement model or not.\"\"\""},{"line_number":44,"context_line":"        PROVIDERS.resource_api.check_project_depth("},{"line_number":45,"context_line":"            self.enforcement_model.MAX_PROJECT_TREE_DEPTH)"},{"line_number":46,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"5f7c97a3_fbb1f592","line":43,"range":{"start_line":43,"start_character":11,"end_line":43,"end_character":41},"in_reply_to":"5f7c97a3_fbf9f581","updated":"2018-07-24 14:34:46.000000000","message":"Done in https://review.openstack.org/#/c/585379/","commit_id":"8e44aa3b97e1892b0648177d1cb5836cfe5795e7"}],"keystone/resource/backends/base.py":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"8cc7199296527379099a5286da43bbf308c85772","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"5f7c97a3_36b30d51","line":274,"updated":"2018-07-12 10:49:57.000000000","message":"Why do we need a new method in the driver? Why is http://git.openstack.org/cgit/openstack/keystone/tree/keystone/resource/core.py#n70 not good enough?","commit_id":"3dfd1cd89c0bb91df207ccc9b59a7a29c2e4c206"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"ad2dbf1879f6f1746d7348625fd84d727e006ba4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"5f7c97a3_b17de7e7","line":274,"in_reply_to":"5f7c97a3_36b30d51","updated":"2018-07-12 12:03:32.000000000","message":"that method is only used for one project tree. i.e. if there are there trees in db:\n   A       E      G\n  / \\      |    \n B   C     F\nwe\u0027ll first get each tree, then check tree times(max), the performance is very low. It only works well when create a new project.\n\nIn this case, we\u0027ll scan the whole backend, so that the SQL action is more effective IMO.","commit_id":"3dfd1cd89c0bb91df207ccc9b59a7a29c2e4c206"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"19493c96c739986dabe1685ed1ffe9090f76c40d","unresolved":false,"context_lines":[{"line_number":263,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"    def check_project_depth(self, max_depth):"},{"line_number":266,"context_line":"        \"\"\"check the projects depth in the backend whether exceed the limit."},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        :param max_depth: the limit depth that project depth should not exceed."},{"line_number":269,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"5f7c97a3_6b20334c","line":266,"range":{"start_line":266,"start_character":11,"end_line":266,"end_character":16},"updated":"2018-07-18 15:44:54.000000000","message":"nit: Check*","commit_id":"679836bcbe6ae63ee5fb0d0926287c8f59ede073"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"f7de3fb0f86c1bf6075812b8b96d6c9885ea4193","unresolved":false,"context_lines":[{"line_number":263,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"    def check_project_depth(self, max_depth):"},{"line_number":266,"context_line":"        \"\"\"check the projects depth in the backend whether exceed the limit."},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        :param max_depth: the limit depth that project depth should not exceed."},{"line_number":269,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"5f7c97a3_13776c0a","line":266,"range":{"start_line":266,"start_character":11,"end_line":266,"end_character":16},"in_reply_to":"5f7c97a3_6b20334c","updated":"2018-07-19 03:45:48.000000000","message":"Done","commit_id":"679836bcbe6ae63ee5fb0d0926287c8f59ede073"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"19493c96c739986dabe1685ed1ffe9090f76c40d","unresolved":false,"context_lines":[{"line_number":265,"context_line":"    def check_project_depth(self, max_depth):"},{"line_number":266,"context_line":"        \"\"\"check the projects depth in the backend whether exceed the limit."},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        :param max_depth: the limit depth that project depth should not exceed."},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"        :returns: the exceeded project\u0027s id or None if no exceeding."},{"line_number":271,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"5f7c97a3_4b1bf71a","line":268,"updated":"2018-07-18 15:44:54.000000000","message":"nit: \n\n  :type max_depth: integer","commit_id":"679836bcbe6ae63ee5fb0d0926287c8f59ede073"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"f7de3fb0f86c1bf6075812b8b96d6c9885ea4193","unresolved":false,"context_lines":[{"line_number":265,"context_line":"    def check_project_depth(self, max_depth):"},{"line_number":266,"context_line":"        \"\"\"check the projects depth in the backend whether exceed the limit."},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        :param max_depth: the limit depth that project depth should not exceed."},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"        :returns: the exceeded project\u0027s id or None if no exceeding."},{"line_number":271,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"5f7c97a3_7316e0a3","line":268,"in_reply_to":"5f7c97a3_4b1bf71a","updated":"2018-07-19 03:45:48.000000000","message":"Done","commit_id":"679836bcbe6ae63ee5fb0d0926287c8f59ede073"}],"keystone/resource/backends/sql.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"7a18d03e71794f032ab4f393c6e01c321d0c8946","unresolved":false,"context_lines":[{"line_number":276,"context_line":"                                \u0027deleted.\u0027, project_id)"},{"line_number":277,"context_line":"            query.delete(synchronize_session\u003dFalse)"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    def check_project_depth(self, max_depth):"},{"line_number":280,"context_line":"        with sql.session_for_read() as session:"},{"line_number":281,"context_line":"            obj_list \u003d []"},{"line_number":282,"context_line":"            # We\u0027ll outerjoin max_depth + 2 times. One more time is for"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_5a4f15bd","line":279,"range":{"start_line":279,"start_character":8,"end_line":279,"end_character":27},"updated":"2018-07-09 21:09:27.000000000","message":"This will require a change to interface this class implements: \n\nhttps://git.openstack.org/cgit/openstack/keystone/tree/keystone/resource/backends/base.py#n43","commit_id":"3c12c1a011e8c12f66a43ae847e0fb23e45d5548"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"abf99db8bc20b1a0b85b8cbaba9ae17d589fa185","unresolved":false,"context_lines":[{"line_number":276,"context_line":"                                \u0027deleted.\u0027, project_id)"},{"line_number":277,"context_line":"            query.delete(synchronize_session\u003dFalse)"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    def check_project_depth(self, max_depth):"},{"line_number":280,"context_line":"        with sql.session_for_read() as session:"},{"line_number":281,"context_line":"            obj_list \u003d []"},{"line_number":282,"context_line":"            # We\u0027ll outerjoin max_depth + 2 times. One more time is for"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_ceea7e0c","line":279,"range":{"start_line":279,"start_character":8,"end_line":279,"end_character":27},"in_reply_to":"5f7c97a3_5a4f15bd","updated":"2018-07-10 07:31:27.000000000","message":"Done","commit_id":"3c12c1a011e8c12f66a43ae847e0fb23e45d5548"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"7a18d03e71794f032ab4f393c6e01c321d0c8946","unresolved":false,"context_lines":[{"line_number":279,"context_line":"    def check_project_depth(self, max_depth):"},{"line_number":280,"context_line":"        with sql.session_for_read() as session:"},{"line_number":281,"context_line":"            obj_list \u003d []"},{"line_number":282,"context_line":"            # We\u0027ll outerjoin max_depth + 2 times. One more time is for"},{"line_number":283,"context_line":"            # project as domain. Another time is to ensure there is no more"},{"line_number":284,"context_line":"            # descendants."},{"line_number":285,"context_line":"            for _ in range(max_depth + 2):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_9a328d5c","line":282,"range":{"start_line":282,"start_character":42,"end_line":282,"end_character":43},"updated":"2018-07-09 21:09:27.000000000","message":"I\u0027m not sure I completely understand this constant.","commit_id":"3c12c1a011e8c12f66a43ae847e0fb23e45d5548"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"abf99db8bc20b1a0b85b8cbaba9ae17d589fa185","unresolved":false,"context_lines":[{"line_number":279,"context_line":"    def check_project_depth(self, max_depth):"},{"line_number":280,"context_line":"        with sql.session_for_read() as session:"},{"line_number":281,"context_line":"            obj_list \u003d []"},{"line_number":282,"context_line":"            # We\u0027ll outerjoin max_depth + 2 times. One more time is for"},{"line_number":283,"context_line":"            # project as domain. Another time is to ensure there is no more"},{"line_number":284,"context_line":"            # descendants."},{"line_number":285,"context_line":"            for _ in range(max_depth + 2):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_6eed6a22","line":282,"range":{"start_line":282,"start_character":42,"end_line":282,"end_character":43},"in_reply_to":"5f7c97a3_9a328d5c","updated":"2018-07-10 07:31:27.000000000","message":"oh, it\u0027s wrong here, I\u0027ll update it.","commit_id":"3c12c1a011e8c12f66a43ae847e0fb23e45d5548"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"7a18d03e71794f032ab4f393c6e01c321d0c8946","unresolved":false,"context_lines":[{"line_number":295,"context_line":"            value \u003d query.filter(obj_list[-1].id !\u003d expression.null()).first()"},{"line_number":296,"context_line":""},{"line_number":297,"context_line":"            if value:"},{"line_number":298,"context_line":"                raise exception.LimitTreeExceedError(value[max_depth + 1].id,"},{"line_number":299,"context_line":"                                                     max_depth)"},{"line_number":300,"context_line":""},{"line_number":301,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_ba774908","line":298,"range":{"start_line":298,"start_character":32,"end_line":298,"end_character":52},"updated":"2018-07-09 21:09:27.000000000","message":"This seems like an error that should be raised by keystone\u0027s business logic layer. It feels like this method should just return the depth, regardless of the enforcement model being used. The manager should determine if it\u0027s acceptable to use within a given enforcement model.","commit_id":"3c12c1a011e8c12f66a43ae847e0fb23e45d5548"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"abf99db8bc20b1a0b85b8cbaba9ae17d589fa185","unresolved":false,"context_lines":[{"line_number":295,"context_line":"            value \u003d query.filter(obj_list[-1].id !\u003d expression.null()).first()"},{"line_number":296,"context_line":""},{"line_number":297,"context_line":"            if value:"},{"line_number":298,"context_line":"                raise exception.LimitTreeExceedError(value[max_depth + 1].id,"},{"line_number":299,"context_line":"                                                     max_depth)"},{"line_number":300,"context_line":""},{"line_number":301,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_4963c8dd","line":298,"range":{"start_line":298,"start_character":32,"end_line":298,"end_character":52},"in_reply_to":"5f7c97a3_ba774908","updated":"2018-07-10 07:31:27.000000000","message":"Done","commit_id":"3c12c1a011e8c12f66a43ae847e0fb23e45d5548"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"9124766184118dd9253bf851fc668a8c4928ea92","unresolved":false,"context_lines":[{"line_number":324,"context_line":""},{"line_number":325,"context_line":"            query \u003d session.query(*obj_list)"},{"line_number":326,"context_line":"            index \u003d 0"},{"line_number":327,"context_line":"            while index !\u003d max_depth + 1:"},{"line_number":328,"context_line":"                query \u003d query.outerjoin("},{"line_number":329,"context_line":"                    obj_list[index + 1],"},{"line_number":330,"context_line":"                    obj_list[index].id \u003d\u003d obj_list[index + 1].parent_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f7c97a3_dc03bcbc","line":327,"updated":"2018-07-13 11:44:59.000000000","message":"(nit) it would be more pythonic to use a foreach loop over a range here","commit_id":"cd7f2f15441448492dfea143ce9f30aa98885ead"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"918a02e1466e936460a4e59e25a5e1ba11c3991f","unresolved":false,"context_lines":[{"line_number":324,"context_line":""},{"line_number":325,"context_line":"            query \u003d session.query(*obj_list)"},{"line_number":326,"context_line":"            index \u003d 0"},{"line_number":327,"context_line":"            while index !\u003d max_depth + 1:"},{"line_number":328,"context_line":"                query \u003d query.outerjoin("},{"line_number":329,"context_line":"                    obj_list[index + 1],"},{"line_number":330,"context_line":"                    obj_list[index].id \u003d\u003d obj_list[index + 1].parent_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f7c97a3_fbc7833c","line":327,"in_reply_to":"5f7c97a3_dc03bcbc","updated":"2018-07-16 02:08:10.000000000","message":"Done","commit_id":"cd7f2f15441448492dfea143ce9f30aa98885ead"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"9124766184118dd9253bf851fc668a8c4928ea92","unresolved":false,"context_lines":[{"line_number":333,"context_line":"                obj_list[-1].id !\u003d expression.null()).first()"},{"line_number":334,"context_line":""},{"line_number":335,"context_line":"            if exceeded_line:"},{"line_number":336,"context_line":"                return exceeded_line[max_depth + 1].id"},{"line_number":337,"context_line":""},{"line_number":338,"context_line":""},{"line_number":339,"context_line":"class Project(sql.ModelBase, sql.ModelDictMixinWithExtras):"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f7c97a3_3cf430d0","line":336,"updated":"2018-07-13 11:44:59.000000000","message":"I don\u0027t think it really makes sense to return one ID. There could be multiple leaf projects that bring the hierarchy over the limit.","commit_id":"cd7f2f15441448492dfea143ce9f30aa98885ead"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"918a02e1466e936460a4e59e25a5e1ba11c3991f","unresolved":false,"context_lines":[{"line_number":333,"context_line":"                obj_list[-1].id !\u003d expression.null()).first()"},{"line_number":334,"context_line":""},{"line_number":335,"context_line":"            if exceeded_line:"},{"line_number":336,"context_line":"                return exceeded_line[max_depth + 1].id"},{"line_number":337,"context_line":""},{"line_number":338,"context_line":""},{"line_number":339,"context_line":"class Project(sql.ModelBase, sql.ModelDictMixinWithExtras):"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f7c97a3_5b023774","line":336,"in_reply_to":"5f7c97a3_3cf430d0","updated":"2018-07-16 02:08:10.000000000","message":"yeah, then we can return a list.","commit_id":"cd7f2f15441448492dfea143ce9f30aa98885ead"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"30dbdf8e89d14c2e1345496fce4c43c2d4b67e6b","unresolved":false,"context_lines":[{"line_number":308,"context_line":"            # project1 is the root. It is a project or a domain. If project1 is"},{"line_number":309,"context_line":"            # a project, there must exist a line that project1 is its domain."},{"line_number":310,"context_line":"            #"},{"line_number":311,"context_line":"            # we got 6 lines here."},{"line_number":312,"context_line":"            #"},{"line_number":313,"context_line":"            # 1). the 1, 2 line means project project_a has no child, the depth"},{"line_number":314,"context_line":"            #    is 1."}],"source_content_type":"text/x-python","patch_set":10,"id":"5f7c97a3_96c5065f","line":311,"range":{"start_line":311,"start_character":14,"end_line":311,"end_character":34},"updated":"2018-07-16 04:25:37.000000000","message":"would be useful to add the line numbers in the table. Great comment, BTW.","commit_id":"cc854874a6c525914dffdadc5a7185bd6acbaaff"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"19493c96c739986dabe1685ed1ffe9090f76c40d","unresolved":false,"context_lines":[{"line_number":279,"context_line":"    def check_project_depth(self, max_depth):"},{"line_number":280,"context_line":"        with sql.session_for_read() as session:"},{"line_number":281,"context_line":"            obj_list \u003d []"},{"line_number":282,"context_line":"            # Using db table self outerjoin to find the project descendants."},{"line_number":283,"context_line":"            #"},{"line_number":284,"context_line":"            # We\u0027ll only outerjoin the project table (max_depth + 1) times to"},{"line_number":285,"context_line":"            # check whether current project tree exceed the max depth limit."}],"source_content_type":"text/x-python","patch_set":11,"id":"5f7c97a3_ebbd23b2","line":282,"updated":"2018-07-18 15:44:54.000000000","message":"This feels like a lot to process for a backend. Would it be easier to process this in the manager with a list of all projects instead? That also might prevent us from having to change the interface, or overload the return type since the resource manager could raise the exception directly.","commit_id":"679836bcbe6ae63ee5fb0d0926287c8f59ede073"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"947f1ad6ad97dccbc2d3217cfe0ca7a53815ae19","unresolved":false,"context_lines":[{"line_number":279,"context_line":"    def check_project_depth(self, max_depth):"},{"line_number":280,"context_line":"        with sql.session_for_read() as session:"},{"line_number":281,"context_line":"            obj_list \u003d []"},{"line_number":282,"context_line":"            # Using db table self outerjoin to find the project descendants."},{"line_number":283,"context_line":"            #"},{"line_number":284,"context_line":"            # We\u0027ll only outerjoin the project table (max_depth + 1) times to"},{"line_number":285,"context_line":"            # check whether current project tree exceed the max depth limit."}],"source_content_type":"text/x-python","patch_set":11,"id":"5f7c97a3_5bb7c9d8","line":282,"in_reply_to":"5f7c97a3_1361ac11","updated":"2018-07-24 14:25:10.000000000","message":"Yeah - that\u0027s what I was getting at, but I agree that it wouldn\u0027t be as efficient offloading the processing to SQL. The main thing I was concerned about (and maybe I shouldn\u0027t) be is complicated methods in the driver, but it\u0027s a requirement for this use case.","commit_id":"679836bcbe6ae63ee5fb0d0926287c8f59ede073"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"f7de3fb0f86c1bf6075812b8b96d6c9885ea4193","unresolved":false,"context_lines":[{"line_number":279,"context_line":"    def check_project_depth(self, max_depth):"},{"line_number":280,"context_line":"        with sql.session_for_read() as session:"},{"line_number":281,"context_line":"            obj_list \u003d []"},{"line_number":282,"context_line":"            # Using db table self outerjoin to find the project descendants."},{"line_number":283,"context_line":"            #"},{"line_number":284,"context_line":"            # We\u0027ll only outerjoin the project table (max_depth + 1) times to"},{"line_number":285,"context_line":"            # check whether current project tree exceed the max depth limit."}],"source_content_type":"text/x-python","patch_set":11,"id":"5f7c97a3_1361ac11","line":282,"in_reply_to":"5f7c97a3_ebbd23b2","updated":"2018-07-19 03:45:48.000000000","message":"you mean fetch all project from db first, then do the check by a code logic? if so, I don\u0027t suggest do that, because that way will cost lots memory and the performance is not better than the SQL way. Or I misunderstand your proposal?","commit_id":"679836bcbe6ae63ee5fb0d0926287c8f59ede073"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"19493c96c739986dabe1685ed1ffe9090f76c40d","unresolved":false,"context_lines":[{"line_number":319,"context_line":"            # So we can see that if column \"project4_id\" has value, it means"},{"line_number":320,"context_line":"            # some trees hit the max depth limit."},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"            for _ in range(max_depth + 2):"},{"line_number":323,"context_line":"                obj_list.append(orm.aliased(Project))"},{"line_number":324,"context_line":""},{"line_number":325,"context_line":"            query \u003d session.query(*obj_list)"}],"source_content_type":"text/x-python","patch_set":11,"id":"5f7c97a3_ebc1a350","line":322,"range":{"start_line":322,"start_character":39,"end_line":322,"end_character":40},"updated":"2018-07-18 15:44:54.000000000","message":"We should try and associate this constant to a variable name, otherwise it can be confusing to figure out what it really means.","commit_id":"679836bcbe6ae63ee5fb0d0926287c8f59ede073"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"f7de3fb0f86c1bf6075812b8b96d6c9885ea4193","unresolved":false,"context_lines":[{"line_number":319,"context_line":"            # So we can see that if column \"project4_id\" has value, it means"},{"line_number":320,"context_line":"            # some trees hit the max depth limit."},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"            for _ in range(max_depth + 2):"},{"line_number":323,"context_line":"                obj_list.append(orm.aliased(Project))"},{"line_number":324,"context_line":""},{"line_number":325,"context_line":"            query \u003d session.query(*obj_list)"}],"source_content_type":"text/x-python","patch_set":11,"id":"5f7c97a3_f358b089","line":322,"range":{"start_line":322,"start_character":39,"end_line":322,"end_character":40},"in_reply_to":"5f7c97a3_ebc1a350","updated":"2018-07-19 03:45:48.000000000","message":"Done","commit_id":"679836bcbe6ae63ee5fb0d0926287c8f59ede073"}],"keystone/resource/core.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"281775d56fc26906040dea7c5dfeb575592cc48c","unresolved":false,"context_lines":[{"line_number":952,"context_line":"        self.update_project(project_id, project)"},{"line_number":953,"context_line":"        notifications.Audit.deleted(self._PROJECT_TAG, tag)"},{"line_number":954,"context_line":""},{"line_number":955,"context_line":"    def check_project_depth(self, max_depth\u003dNone):"},{"line_number":956,"context_line":"        \"\"\"Check project depth whether greater than input or not\"\"\""},{"line_number":957,"context_line":"        if max_depth:"},{"line_number":958,"context_line":"            self.driver.check_project_depth(max_depth)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_97813ac5","line":955,"updated":"2018-07-06 00:05:09.000000000","message":"This is expensive. We may want to consider memoizing it (cache) in a future patch.","commit_id":"27a45216b115c3681d9bd44b50491fee8fd4e26a"}],"keystone/server/backends.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"281775d56fc26906040dea7c5dfeb575592cc48c","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    # before running keystone."},{"line_number":63,"context_line":"    provider_api.ProviderAPIs.lock_provider_registry()"},{"line_number":64,"context_line":"    try:"},{"line_number":65,"context_line":"        # Check project depth before start process. If fail, Keyston will not"},{"line_number":66,"context_line":"        # start."},{"line_number":67,"context_line":"        drivers[\u0027unified_limit_api\u0027].check_project_depth()"},{"line_number":68,"context_line":"    except exception.LimitTreeExceedError as e:"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_376aa61a","line":65,"range":{"start_line":65,"start_character":61,"end_line":65,"end_character":68},"updated":"2018-07-06 00:05:09.000000000","message":"Keystone","commit_id":"27a45216b115c3681d9bd44b50491fee8fd4e26a"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"7a18d03e71794f032ab4f393c6e01c321d0c8946","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    try:"},{"line_number":65,"context_line":"        # Check project depth before start process. If fail, Keystone will not"},{"line_number":66,"context_line":"        # start."},{"line_number":67,"context_line":"        drivers[\u0027unified_limit_api\u0027].check_project_depth()"},{"line_number":68,"context_line":"    except exception.LimitTreeExceedError as e:"},{"line_number":69,"context_line":"        LOG.critical(e)"},{"line_number":70,"context_line":"        sys.exit(1)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_da632540","line":67,"updated":"2018-07-09 21:09:27.000000000","message":"If the resource manager is instantiated before the limit manager, we might be able to get away with doing this validation in the limit provider\u0027s __init__ method instead of special-casing it here.","commit_id":"3c12c1a011e8c12f66a43ae847e0fb23e45d5548"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"abf99db8bc20b1a0b85b8cbaba9ae17d589fa185","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    try:"},{"line_number":65,"context_line":"        # Check project depth before start process. If fail, Keystone will not"},{"line_number":66,"context_line":"        # start."},{"line_number":67,"context_line":"        drivers[\u0027unified_limit_api\u0027].check_project_depth()"},{"line_number":68,"context_line":"    except exception.LimitTreeExceedError as e:"},{"line_number":69,"context_line":"        LOG.critical(e)"},{"line_number":70,"context_line":"        sys.exit(1)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_7a7bec78","line":67,"in_reply_to":"5f7c97a3_da632540","updated":"2018-07-10 07:31:27.000000000","message":"correct, but then we\u0027ll force the manager init order again. I\u0027m not sure it\u0027s the result we want.","commit_id":"3c12c1a011e8c12f66a43ae847e0fb23e45d5548"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"9124766184118dd9253bf851fc668a8c4928ea92","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    try:"},{"line_number":65,"context_line":"        # Check project depth before start process. If fail, Keystone will not"},{"line_number":66,"context_line":"        # start."},{"line_number":67,"context_line":"        drivers[\u0027unified_limit_api\u0027].check_project_depth()"},{"line_number":68,"context_line":"    except exception.LimitTreeExceedError as e:"},{"line_number":69,"context_line":"        LOG.critical(e)"},{"line_number":70,"context_line":"        sys.exit(1)"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f7c97a3_1c64d4b2","line":67,"range":{"start_line":67,"start_character":17,"end_line":67,"end_character":34},"updated":"2018-07-13 11:44:59.000000000","message":"Shouldn\u0027t this be the resource_api?","commit_id":"cd7f2f15441448492dfea143ce9f30aa98885ead"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"918a02e1466e936460a4e59e25a5e1ba11c3991f","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    try:"},{"line_number":65,"context_line":"        # Check project depth before start process. If fail, Keystone will not"},{"line_number":66,"context_line":"        # start."},{"line_number":67,"context_line":"        drivers[\u0027unified_limit_api\u0027].check_project_depth()"},{"line_number":68,"context_line":"    except exception.LimitTreeExceedError as e:"},{"line_number":69,"context_line":"        LOG.critical(e)"},{"line_number":70,"context_line":"        sys.exit(1)"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f7c97a3_dbcc0764","line":67,"range":{"start_line":67,"start_character":17,"end_line":67,"end_character":34},"in_reply_to":"5f7c97a3_1c64d4b2","updated":"2018-07-16 02:08:10.000000000","message":"because we should get the max depth first form unified_limit_api[1]\n[1]:https://review.openstack.org/#/c/580331/9/keystone/limit/core.py\n\nwe can use \"resource_api\" here and then get the max depth from resource manager, but I think it\u0027ll be a little ugly, like: max_depth \u003d self.unified_limit_api.enforcement_model.MAX_PROJECT_TREE_DEPTH\n\nI hope the enforcement_model is only open for unified_limit_api manager it self.","commit_id":"cd7f2f15441448492dfea143ce9f30aa98885ead"}],"releasenotes/notes/bp-strict-two-level-model.yaml":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"7a18d03e71794f032ab4f393c6e01c321d0c8946","unresolved":false,"context_lines":[{"line_number":18,"context_line":""},{"line_number":19,"context_line":"   When try to use this model but the project depth exceed 2 already, Keystone"},{"line_number":20,"context_line":"   process will fail to start. Operators should chose another available model"},{"line_number":21,"context_line":"   to fix the issue first."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":" - \u003e"},{"line_number":24,"context_line":"   [`blueprint strict-two-level-model \u003chttps://blueprints.launchpad.net/keystone/+spec/strict-two-level-model\u003e`_]"}],"source_content_type":"text/x-yaml","patch_set":4,"id":"5f7c97a3_3a6b391f","line":21,"updated":"2018-07-09 21:09:27.000000000","message":"This change is also changing a backend interface. We should have a dedicated release note for people providing their own resource backends.","commit_id":"3c12c1a011e8c12f66a43ae847e0fb23e45d5548"},{"author":{"_account_id":15054,"name":"wangxiyuan","email":"wangxiyuan1007@gmail.com","username":"wangxiyuan"},"change_message_id":"abf99db8bc20b1a0b85b8cbaba9ae17d589fa185","unresolved":false,"context_lines":[{"line_number":18,"context_line":""},{"line_number":19,"context_line":"   When try to use this model but the project depth exceed 2 already, Keystone"},{"line_number":20,"context_line":"   process will fail to start. Operators should chose another available model"},{"line_number":21,"context_line":"   to fix the issue first."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":" - \u003e"},{"line_number":24,"context_line":"   [`blueprint strict-two-level-model \u003chttps://blueprints.launchpad.net/keystone/+spec/strict-two-level-model\u003e`_]"}],"source_content_type":"text/x-yaml","patch_set":4,"id":"5f7c97a3_b34d2f9a","line":21,"in_reply_to":"5f7c97a3_3a6b391f","updated":"2018-07-10 07:31:27.000000000","message":"Done","commit_id":"3c12c1a011e8c12f66a43ae847e0fb23e45d5548"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"bc965127158d1ae0d28404567a533f58f9b6384f","unresolved":false,"context_lines":[{"line_number":18,"context_line":"   `403 Forbidden` error will be raised."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"   When try to use this model but the project depth exceed 2 already, Keystone"},{"line_number":21,"context_line":"   process will fail to start. Operators should chose another available model"},{"line_number":22,"context_line":"   to fix the issue first."},{"line_number":23,"context_line":""},{"line_number":24,"context_line":" - \u003e"}],"source_content_type":"text/x-yaml","patch_set":12,"id":"5f7c97a3_5bc6e917","line":21,"range":{"start_line":21,"start_character":48,"end_line":21,"end_character":53},"updated":"2018-07-24 14:30:41.000000000","message":"choose*","commit_id":"8e44aa3b97e1892b0648177d1cb5836cfe5795e7"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"ac00d57aa51fb2fafde53758af94d59a193aae85","unresolved":false,"context_lines":[{"line_number":18,"context_line":"   `403 Forbidden` error will be raised."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"   When try to use this model but the project depth exceed 2 already, Keystone"},{"line_number":21,"context_line":"   process will fail to start. Operators should chose another available model"},{"line_number":22,"context_line":"   to fix the issue first."},{"line_number":23,"context_line":""},{"line_number":24,"context_line":" - \u003e"}],"source_content_type":"text/x-yaml","patch_set":12,"id":"5f7c97a3_bbab7d1d","line":21,"range":{"start_line":21,"start_character":48,"end_line":21,"end_character":53},"in_reply_to":"5f7c97a3_5bc6e917","updated":"2018-07-24 14:34:46.000000000","message":"Done in https://review.openstack.org/#/c/585379/","commit_id":"8e44aa3b97e1892b0648177d1cb5836cfe5795e7"}]}
