)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"da98a7c06613e96f9c7cc240d0394fe43ed1daaf","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"c1ee9aa0_16d645fc","updated":"2026-06-08 12:54:19.000000000","message":"Missing: `extraroutes` API quota enforcement","commit_id":"3bd44ed4502859e2c01a24b96e7011a56f2468a3"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"b021875b93f76cd2d12e75e85da800294fafad8b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"6c7d7769_db676540","in_reply_to":"c1ee9aa0_16d645fc","updated":"2026-06-11 07:10:39.000000000","message":"Done: this API is calling `update_router`, that has the quota enforcement.","commit_id":"3bd44ed4502859e2c01a24b96e7011a56f2468a3"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"8e80c259405af5da5d59868835c835ec15966e01","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"3eff3772_640d19b0","updated":"2026-06-11 07:35:37.000000000","message":"*NOTE*: added a documentation patch (https://review.opendev.org/c/openstack/neutron/+/992854) to update the ops-quota file","commit_id":"f2ffed2f968db97d8c84856d4a6f4858f586517a"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"e3ec4ddfe6dcbcaf0e6eddd90a8000144130bcb5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"0b7c1c14_10571a64","updated":"2026-06-15 10:11:06.000000000","message":"I need to refactor this patch","commit_id":"f2ffed2f968db97d8c84856d4a6f4858f586517a"},{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"8d62f8f088c11d5e450a752e18714cffeb2f2abf","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":6,"id":"4df66d83_3ca6a32d","updated":"2026-06-15 10:14:32.000000000","message":"This patch is IMO doing something opposite to what the spec https://review.opendev.org/c/openstack/neutron-specs/+/992234 is saying. According to the spec new quota option should be limiting number of routes per router, but this implementation is enforcing quota per project in total, no matter how many of routes are in each router.","commit_id":"f2ffed2f968db97d8c84856d4a6f4858f586517a"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"9994c98931876beab7d0377c6dd005b7e4957829","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"5989f043_7f2ba64d","in_reply_to":"4df66d83_3ca6a32d","updated":"2026-06-15 10:43:05.000000000","message":"You are 100% right","commit_id":"f2ffed2f968db97d8c84856d4a6f4858f586517a"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"ab2b293dcd240ddaac94952c301a31508cf7ec62","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"9c3a08c3_0e4b75b8","updated":"2026-06-17 11:15:24.000000000","message":"I\u0027ll push a new PS","commit_id":"e64ec6d0b61fec041edf02c8b1ad87f8216096bb"},{"author":{"_account_id":32586,"name":"Elvira García Ruiz","display_name":"Elvira","email":"egarciar@redhat.com","username":"elvira"},"change_message_id":"73ac62f1e14560a02503d0d4b6fff060dc0dd7c4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"40af97f1_f809d07a","updated":"2026-06-22 12:17:56.000000000","message":"It looks good to me although (nit) I saw references to max_route (to set its default value) in the unit tests i.e. neutron/tests/unit/extensions/test_qos_fip.py. Wondering if this is still needed.","commit_id":"e1799a38a775aa8c251728cb350e5fcfa355d677"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"80e4e30e0f254880c87dd5c2b8a8be74b0ec47a3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"09afb885_faa69d7c","updated":"2026-06-19 06:41:36.000000000","message":"recheck neutron-ovs-tempest-dvr-ha-multinode-full","commit_id":"e1799a38a775aa8c251728cb350e5fcfa355d677"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"788bde080f9cc8d5af06450c1e49bbefa1ff7259","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"6587ba6a_ff0091d5","updated":"2026-06-18 14:00:29.000000000","message":"recheck neutron-ovs-tempest-multinode-full","commit_id":"e1799a38a775aa8c251728cb350e5fcfa355d677"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"a50708af319b50a7ec010156617ef336fee4857e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"20bdbfe8_6cbf98da","updated":"2026-06-22 23:09:21.000000000","message":"recheck unrelated tempest failure","commit_id":"e1799a38a775aa8c251728cb350e5fcfa355d677"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"43019e419d81073b9dd1f09f537a52c3e79bb5a8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"264c6483_5e09458d","in_reply_to":"40af97f1_f809d07a","updated":"2026-06-23 05:43:01.000000000","message":"You are right: https://review.opendev.org/c/openstack/neutron/+/994393","commit_id":"e1799a38a775aa8c251728cb350e5fcfa355d677"}],"neutron/cmd/upgrade_checks/checks.py":[{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"b64fa24eefdbea05bd8f9f9c98db28b441e5abaa","unresolved":true,"context_lines":[{"line_number":630,"context_line":"            return upgradecheck.Result("},{"line_number":631,"context_line":"                upgradecheck.Code.WARNING,"},{"line_number":632,"context_line":"                _(\u0027The \"max_routes\" configuration option is set to \u0027"},{"line_number":633,"context_line":"                  \u0027%(value)d but this option has been removed. The \u0027"},{"line_number":634,"context_line":"                  \u0027per-router route limit is now enforced by the \u0027"},{"line_number":635,"context_line":"                  \u0027\"quota_router_route\" quota in the [QUOTAS] section \u0027"},{"line_number":636,"context_line":"                  \u0027(default: %(default)d). Please update the quota \u0027"}],"source_content_type":"text/x-python","patch_set":9,"id":"038d534b_ba662ac0","line":633,"range":{"start_line":633,"start_character":38,"end_line":633,"end_character":61},"updated":"2026-06-16 13:27:59.000000000","message":"it is not yet removed but deprecated, right?","commit_id":"e64ec6d0b61fec041edf02c8b1ad87f8216096bb"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"6636c93c449d0666eaef0a0e45a83a1e60ca5bd7","unresolved":false,"context_lines":[{"line_number":630,"context_line":"            return upgradecheck.Result("},{"line_number":631,"context_line":"                upgradecheck.Code.WARNING,"},{"line_number":632,"context_line":"                _(\u0027The \"max_routes\" configuration option is set to \u0027"},{"line_number":633,"context_line":"                  \u0027%(value)d but this option has been removed. The \u0027"},{"line_number":634,"context_line":"                  \u0027per-router route limit is now enforced by the \u0027"},{"line_number":635,"context_line":"                  \u0027\"quota_router_route\" quota in the [QUOTAS] section \u0027"},{"line_number":636,"context_line":"                  \u0027(default: %(default)d). Please update the quota \u0027"}],"source_content_type":"text/x-python","patch_set":9,"id":"5f2604e9_dd929457","line":633,"range":{"start_line":633,"start_character":38,"end_line":633,"end_character":61},"in_reply_to":"038d534b_ba662ac0","updated":"2026-06-17 11:15:11.000000000","message":"Actually we remove it in this patch.\n\nMaybe we need to:\n* Keep the `max_routes` configuration variable, adding a comment.\n* Also add a warning message if the `max_routes` is configured with a different value (30), saying that this knob is not longer used and to use the quota instead.","commit_id":"e64ec6d0b61fec041edf02c8b1ad87f8216096bb"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"2566efd1cb48f5b3c1355d8e97855c4072227a03","unresolved":false,"context_lines":[{"line_number":630,"context_line":"            return upgradecheck.Result("},{"line_number":631,"context_line":"                upgradecheck.Code.WARNING,"},{"line_number":632,"context_line":"                _(\u0027The \"max_routes\" configuration option is set to \u0027"},{"line_number":633,"context_line":"                  \u0027%(value)d but this option has been removed. The \u0027"},{"line_number":634,"context_line":"                  \u0027per-router route limit is now enforced by the \u0027"},{"line_number":635,"context_line":"                  \u0027\"quota_router_route\" quota in the [QUOTAS] section \u0027"},{"line_number":636,"context_line":"                  \u0027(default: %(default)d). Please update the quota \u0027"}],"source_content_type":"text/x-python","patch_set":9,"id":"d9704db8_7b778973","line":633,"range":{"start_line":633,"start_character":38,"end_line":633,"end_character":61},"in_reply_to":"5f2604e9_dd929457","updated":"2026-06-18 09:36:02.000000000","message":"Actually, this is how it should be. We can\u0027t have both together. This is why we have this upgrade check, to inform to the user that the configuration must be updated and this knob is no longer relevant.","commit_id":"e64ec6d0b61fec041edf02c8b1ad87f8216096bb"},{"author":{"_account_id":8313,"name":"Lajos Katona","display_name":"lajoskatona","email":"katonalala@gmail.com","username":"elajkat","status":"Ericsson Software Technology"},"change_message_id":"0bf58cbc771b990006e37abf6d79bbfbc6620b9c","unresolved":true,"context_lines":[{"line_number":625,"context_line":"        section. If the operator had set ``max_routes`` to a non-default"},{"line_number":626,"context_line":"        value, they need to configure the new quota instead."},{"line_number":627,"context_line":"        \"\"\""},{"line_number":628,"context_line":"        default_max_routes \u003d 30"},{"line_number":629,"context_line":"        if cfg.CONF.max_routes !\u003d default_max_routes:"},{"line_number":630,"context_line":"            return upgradecheck.Result("},{"line_number":631,"context_line":"                upgradecheck.Code.WARNING,"}],"source_content_type":"text/x-python","patch_set":10,"id":"fa54ddf4_4781cc40","line":628,"range":{"start_line":628,"start_character":29,"end_line":628,"end_character":31},"updated":"2026-06-22 12:20:22.000000000","message":"nit: this should be DEFAULT_QUOTA_ROUTER_ROUTE neutron.conf.quota","commit_id":"e1799a38a775aa8c251728cb350e5fcfa355d677"}],"neutron/conf/quota.py":[{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"20b4bd8d47fa4de4fcf5468d9f9d1f7708e6dc24","unresolved":true,"context_lines":[{"line_number":100,"context_line":"    cfg.IntOpt(\u0027quota_router_route\u0027,"},{"line_number":101,"context_line":"               default\u003dDEFAULT_QUOTA_ROUTER_ROUTE,"},{"line_number":102,"context_line":"               help\u003d_(\u0027Number of router routes allowed per project. \u0027"},{"line_number":103,"context_line":"                      \u0027A negative value means unlimited.\u0027)),"},{"line_number":104,"context_line":"]"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"# rbac_quota_opts from neutron/extensions/rbac.py"}],"source_content_type":"text/x-python","patch_set":6,"id":"37c67ef9_8761e864","line":103,"updated":"2026-06-11 17:21:51.000000000","message":"So I understand these are all singular, but the resultant quota looking at your doc change is plural. For example, routers, floating_ips, etc. To be consistent this should be viewable as \"router_routes\", maybe it\u0027s just a typo in the other change?","commit_id":"f2ffed2f968db97d8c84856d4a6f4858f586517a"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"f8996a679b8f5abdfd0c819c9729f291a813809f","unresolved":false,"context_lines":[{"line_number":100,"context_line":"    cfg.IntOpt(\u0027quota_router_route\u0027,"},{"line_number":101,"context_line":"               default\u003dDEFAULT_QUOTA_ROUTER_ROUTE,"},{"line_number":102,"context_line":"               help\u003d_(\u0027Number of router routes allowed per project. \u0027"},{"line_number":103,"context_line":"                      \u0027A negative value means unlimited.\u0027)),"},{"line_number":104,"context_line":"]"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"# rbac_quota_opts from neutron/extensions/rbac.py"}],"source_content_type":"text/x-python","patch_set":6,"id":"61c0debc_0d34ea7a","line":103,"in_reply_to":"37c67ef9_8761e864","updated":"2026-06-12 11:49:30.000000000","message":"Yeah, the doc change is wrong. Both this patch and the spec use \"router_route\" in singular. Also the other network quotas use the singular too.","commit_id":"f2ffed2f968db97d8c84856d4a6f4858f586517a"}],"neutron/db/extraroute_db.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"136de303e9fa17e11ca86dd782d4d1bbe3b7c1b9","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    \"\"\"Mixin class to support extra route configuration on router.\"\"\""},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    @staticmethod"},{"line_number":46,"context_line":"    def get_router_routes_count(context, filters\u003dNone):"},{"line_number":47,"context_line":"        \"\"\"Count all router routes for the given project(s)."},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"        For parity with other resources that apply to a single resource"},{"line_number":50,"context_line":"        (``server_group_members`` in Nova, ``per_volume_gigabytes`` in Cinder),"},{"line_number":51,"context_line":"        this method, used by the quota engine to count the used routes per"},{"line_number":52,"context_line":"        router in ``neutron.quota.resource._count_resource``, will return"},{"line_number":53,"context_line":"        always zero."},{"line_number":54,"context_line":"        \"\"\""},{"line_number":55,"context_line":"        return 0"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    @staticmethod"},{"line_number":58,"context_line":"    @resource_extend.extends([l3_apidef.ROUTERS])"},{"line_number":59,"context_line":"    def _extend_router_dict_extraroute(router_res, router_db):"}],"source_content_type":"text/x-python","patch_set":8,"id":"11cee986_0e771a13","line":56,"range":{"start_line":46,"start_character":4,"end_line":56,"end_character":1},"updated":"2026-06-15 14:43:27.000000000","message":"@skaplons@redhat.com this is what the spec was expecting: report 0 per project and count per router, but the count is done in the `limit_check`","commit_id":"d7c2bd41d974b0396845cb49a72c685f0f38d0fe"},{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"b64fa24eefdbea05bd8f9f9c98db28b441e5abaa","unresolved":true,"context_lines":[{"line_number":130,"context_line":"            router_route\u003dlen(routes))"},{"line_number":131,"context_line":"        old_routes \u003d self._get_extra_routes_by_router_id(context, router[\u0027id\u0027])"},{"line_number":132,"context_line":"        added, removed \u003d helpers.diff_list_of_dict(old_routes, routes)"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"        LOG.debug(\u0027Added routes are %s\u0027, added)"},{"line_number":135,"context_line":"        for route in added:"},{"line_number":136,"context_line":"            l3_obj.RouterRoute("}],"source_content_type":"text/x-python","patch_set":9,"id":"123e8789_355c38c5","line":133,"updated":"2026-06-16 13:27:59.000000000","message":"nitt nit: unrelated change","commit_id":"e64ec6d0b61fec041edf02c8b1ad87f8216096bb"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"6636c93c449d0666eaef0a0e45a83a1e60ca5bd7","unresolved":false,"context_lines":[{"line_number":130,"context_line":"            router_route\u003dlen(routes))"},{"line_number":131,"context_line":"        old_routes \u003d self._get_extra_routes_by_router_id(context, router[\u0027id\u0027])"},{"line_number":132,"context_line":"        added, removed \u003d helpers.diff_list_of_dict(old_routes, routes)"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"        LOG.debug(\u0027Added routes are %s\u0027, added)"},{"line_number":135,"context_line":"        for route in added:"},{"line_number":136,"context_line":"            l3_obj.RouterRoute("}],"source_content_type":"text/x-python","patch_set":9,"id":"a47977f6_cef87500","line":133,"in_reply_to":"123e8789_355c38c5","updated":"2026-06-17 11:15:11.000000000","message":"Done","commit_id":"e64ec6d0b61fec041edf02c8b1ad87f8216096bb"}],"neutron/services/bgp/reconciler.py":[{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"dc02d832bfc26fc825e2507d71769b1621f4ed33","unresolved":true,"context_lines":[{"line_number":89,"context_line":"            LOG.info(\"Waiting for BGP topology reconciler to start\")"},{"line_number":90,"context_line":"            self._started.wait()"},{"line_number":91,"context_line":"            LOG.info(\"BGP topology reconciler is ready\")"},{"line_number":92,"context_line":"        if self.nb_api.has_lock:"},{"line_number":93,"context_line":"            LOG.info(\"Full BGP topology synchronization started\")"},{"line_number":94,"context_line":"            commands.FullSyncBGPTopologyCommand("},{"line_number":95,"context_line":"                self.nb_api, self.sb_api).execute(check_error\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":3,"id":"5d2246ff_be40f3ea","line":92,"updated":"2026-06-03 00:46:03.000000000","message":"This change seems unrelated to the quota check","commit_id":"66fced5fb5b5e4f1df85dd6c3bd66318c19f62f9"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"0f6adaf6d84a3a9fe5c80290c6ad42f7ef0e1ed2","unresolved":false,"context_lines":[{"line_number":89,"context_line":"            LOG.info(\"Waiting for BGP topology reconciler to start\")"},{"line_number":90,"context_line":"            self._started.wait()"},{"line_number":91,"context_line":"            LOG.info(\"BGP topology reconciler is ready\")"},{"line_number":92,"context_line":"        if self.nb_api.has_lock:"},{"line_number":93,"context_line":"            LOG.info(\"Full BGP topology synchronization started\")"},{"line_number":94,"context_line":"            commands.FullSyncBGPTopologyCommand("},{"line_number":95,"context_line":"                self.nb_api, self.sb_api).execute(check_error\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":3,"id":"17a8913c_559a2820","line":92,"in_reply_to":"5d2246ff_be40f3ea","updated":"2026-06-03 06:10:32.000000000","message":"This is because of doing parallel tasks... sorry","commit_id":"66fced5fb5b5e4f1df85dd6c3bd66318c19f62f9"}],"neutron/tests/unit/extensions/test_extraroute.py":[{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"8d62f8f088c11d5e450a752e18714cffeb2f2abf","unresolved":true,"context_lines":[{"line_number":481,"context_line":"                    gw_info \u003d body[\u0027router\u0027][\u0027external_gateway_info\u0027]"},{"line_number":482,"context_line":"                    self.assertIsNone(gw_info)"},{"line_number":483,"context_line":""},{"line_number":484,"context_line":"    def test_router_update_with_too_many_routes_quota(self):"},{"line_number":485,"context_line":"        test_db_base_plugin_v2._set_temporary_quota(\u0027router_route\u0027, 3)"},{"line_number":486,"context_line":"        with self.router() as r:"},{"line_number":487,"context_line":"            with self.subnet(cidr\u003d\u002710.0.1.0/24\u0027) as s:"}],"source_content_type":"text/x-python","patch_set":6,"id":"d8b4bb60_31a3e594","line":484,"updated":"2026-06-15 10:14:32.000000000","message":"what is the difference between this test and `test_router_update_with_too_many_routes` above?","commit_id":"f2ffed2f968db97d8c84856d4a6f4858f586517a"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"9994c98931876beab7d0377c6dd005b7e4957829","unresolved":false,"context_lines":[{"line_number":481,"context_line":"                    gw_info \u003d body[\u0027router\u0027][\u0027external_gateway_info\u0027]"},{"line_number":482,"context_line":"                    self.assertIsNone(gw_info)"},{"line_number":483,"context_line":""},{"line_number":484,"context_line":"    def test_router_update_with_too_many_routes_quota(self):"},{"line_number":485,"context_line":"        test_db_base_plugin_v2._set_temporary_quota(\u0027router_route\u0027, 3)"},{"line_number":486,"context_line":"        with self.router() as r:"},{"line_number":487,"context_line":"            with self.subnet(cidr\u003d\u002710.0.1.0/24\u0027) as s:"}],"source_content_type":"text/x-python","patch_set":6,"id":"65766b02_cb6b43d4","line":484,"in_reply_to":"d8b4bb60_31a3e594","updated":"2026-06-15 10:43:05.000000000","message":"I\u0027ll need to refactor these tests, thanks!","commit_id":"f2ffed2f968db97d8c84856d4a6f4858f586517a"}]}
