)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"a4e7d2048f82ec0d80f648ee8dd779a1e97e3f48","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"053d4859_702265cc","updated":"2026-08-05 07:28:06.000000000","message":"looks good, we need a new n-lib release","commit_id":"5f443ef542c030fc54d42e3f03a5a5ee6e051df1"},{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"11c4cb6e0a7c1fc9181ea0a4fb93de687f00ec7e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"940dad26_89c467ed","updated":"2026-08-04 19:41:50.000000000","message":"thanks. lgtm","commit_id":"5f443ef542c030fc54d42e3f03a5a5ee6e051df1"}],"neutron/objects/router.py":[{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"bcc88b140e400696b6e9478264f5a06aaa500dd0","unresolved":true,"context_lines":[{"line_number":307,"context_line":"    @db_api.CONTEXT_READER"},{"line_number":308,"context_line":"    def get_gateway_router_for_subnet(cls, context, subnet_id):"},{"line_number":309,"context_line":"        \"\"\"Return a Router with an external gateway attached to the subnet."},{"line_number":310,"context_line":""},{"line_number":311,"context_line":"        Performs a single query joining IPAllocation -\u003e Port -\u003e RouterPort"},{"line_number":312,"context_line":"        -\u003e Router, filtering for router interface ports and non-null"},{"line_number":313,"context_line":"        gw_port_id. Returns the Router object or None."},{"line_number":314,"context_line":"        \"\"\""},{"line_number":315,"context_line":"        db_obj \u003d context.session.query(l3.Router).join("}],"source_content_type":"text/x-python","patch_set":5,"id":"33a177e8_9905ec2e","line":312,"range":{"start_line":310,"start_character":0,"end_line":312,"end_character":68},"updated":"2026-08-10 19:26:14.000000000","message":"nit: I feel like this was added by an agent. I noticed that agents like to do lot of `how` comments. But IMO, docs strings and comments should only explain the `why` the `how` is clear from the code. Maybe we can add this to the AGENTS.md.\n\nSorry I know this is outside of the scope of this patch. I can propose that patch","commit_id":"9d79fa6b132bd6cf871b39e529b54f4094e1cc65"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"fa140057a817a29d581645020fbcc96c21decd4a","unresolved":true,"context_lines":[{"line_number":307,"context_line":"    @db_api.CONTEXT_READER"},{"line_number":308,"context_line":"    def get_gateway_router_for_subnet(cls, context, subnet_id):"},{"line_number":309,"context_line":"        \"\"\"Return a Router with an external gateway attached to the subnet."},{"line_number":310,"context_line":""},{"line_number":311,"context_line":"        Performs a single query joining IPAllocation -\u003e Port -\u003e RouterPort"},{"line_number":312,"context_line":"        -\u003e Router, filtering for router interface ports and non-null"},{"line_number":313,"context_line":"        gw_port_id. Returns the Router object or None."},{"line_number":314,"context_line":"        \"\"\""},{"line_number":315,"context_line":"        db_obj \u003d context.session.query(l3.Router).join("}],"source_content_type":"text/x-python","patch_set":5,"id":"4216502b_583f395c","line":312,"range":{"start_line":310,"start_character":0,"end_line":312,"end_character":68},"in_reply_to":"33a177e8_9905ec2e","updated":"2026-08-10 19:31:28.000000000","message":"I tend to disagree with the `why` statement - to me comments or docstrings serve as helpers to understand the code better when it\u0027s not clear from reading the code. The way how to get from subnet_id to the RouterPort is not straight forward to me but if you think the code is good enough, I can remove the docstring, I do not insist on keeping it here.","commit_id":"9d79fa6b132bd6cf871b39e529b54f4094e1cc65"}],"neutron/services/bgp/plugin.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"788b73fd0a3cd25ab7fa16bdb730dfc24961c74f","unresolved":false,"context_lines":[{"line_number":127,"context_line":"            if not router or not router.gw_port_id:"},{"line_number":128,"context_line":"                raise n_exc.BadRequest("},{"line_number":129,"context_line":"                    resource\u003d\u0027subnet\u0027,"},{"line_number":130,"context_line":"                    msg\u003d\u0027The router %(router_id)s must have an external gateway \u0027"},{"line_number":131,"context_line":"                        \u0027set to enable leak_routes.\u0027,"},{"line_number":132,"context_line":"                        router_id\u003drouter_port.device_id)"},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"561a2385_388484b9","line":130,"updated":"2026-07-23 21:44:50.000000000","message":"pep8: E501 line too long (81 \u003e 79 characters)","commit_id":"17351a5495167d12002e4d71731a0cf9e4b626da"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"bbdc616f946b8eaaa9923fb7f087f48a266b07ac","unresolved":true,"context_lines":[{"line_number":55,"context_line":"    def get_plugin_type(cls):"},{"line_number":56,"context_line":"        return \"bgp-service\""},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def _get_router_port_for_subnet(self, context, subnet_id):"},{"line_number":59,"context_line":"        allocations \u003d port_objects.IPAllocation.get_objects("},{"line_number":60,"context_line":"            context, subnet_id\u003dsubnet_id)"},{"line_number":61,"context_line":"        port_ids \u003d [a.port_id for a in allocations if a.port_id]"},{"line_number":62,"context_line":"        if port_ids:"},{"line_number":63,"context_line":"            ports \u003d port_objects.Port.get_objects("},{"line_number":64,"context_line":"                context, id\u003dport_ids,"},{"line_number":65,"context_line":"                device_owner\u003dn_const.DEVICE_OWNER_ROUTER_INTF)"},{"line_number":66,"context_line":"            if ports:"},{"line_number":67,"context_line":"                return ports[0]"},{"line_number":68,"context_line":"        raise n_exc.BadRequest("},{"line_number":69,"context_line":"            resource\u003d\u0027subnet\u0027,"},{"line_number":70,"context_line":"            msg\u003d\u0027The subnet %(subnet_id)s must be attached to a router to \u0027"},{"line_number":71,"context_line":"                \u0027enable leak_routes.\u0027,"},{"line_number":72,"context_line":"                subnet_id\u003dsubnet_id)"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"c684bc48_381ee682","line":70,"range":{"start_line":58,"start_character":0,"end_line":70,"end_character":75},"updated":"2026-08-04 14:18:00.000000000","message":"This looks like it should just be a single join query to me, with a first(), something like:\n\n    port_db \u003d (context.session.query(models_v2.Port)\n               .join(models_v2.IPAllocation,\n                     models_v2.IPAllocation.port_id \u003d\u003d models_v2.Port.id)\n               .filter(models_v2.IPAllocation.subnet_id \u003d\u003d subnet_id)\n               .filter(models_v2.Port.device_owner \u003d\u003d\n                       n_const.DEVICE_OWNER_ROUTER_INTF)\n               .first())\n    if port_db:\n        return port_objects.Port._load_object(context, port_db)","commit_id":"85a5ef63786da0a6e00c578e0835b337a09f0947"},{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"02a6110a68caf6acccd9df58ad90564b56803327","unresolved":true,"context_lines":[{"line_number":67,"context_line":"                return ports[0]"},{"line_number":68,"context_line":"        raise n_exc.BadRequest("},{"line_number":69,"context_line":"            resource\u003d\u0027subnet\u0027,"},{"line_number":70,"context_line":"            msg\u003d\u0027The subnet %(subnet_id)s must be attached to a router to \u0027"},{"line_number":71,"context_line":"                \u0027enable leak_routes.\u0027,"},{"line_number":72,"context_line":"                subnet_id\u003dsubnet_id)"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"b05b8a47_4f4a6401","line":70,"range":{"start_line":70,"start_character":27,"end_line":70,"end_character":42},"updated":"2026-07-31 02:34:26.000000000","message":"is this substitution going to work with the [template](https://opendev.org/openstack/neutron-lib/src/branch/master/neutron_lib/exceptions/__init__.py#L64)? Will it double substitute or just pass literal `%(subnet_id)s`\nwhy not just use `\u0027The subnet %s must be...\u0027 subnet_id`","commit_id":"85a5ef63786da0a6e00c578e0835b337a09f0947"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"9dd3c693a7fdaef018429891606fc5bad60e8396","unresolved":false,"context_lines":[{"line_number":67,"context_line":"                return ports[0]"},{"line_number":68,"context_line":"        raise n_exc.BadRequest("},{"line_number":69,"context_line":"            resource\u003d\u0027subnet\u0027,"},{"line_number":70,"context_line":"            msg\u003d\u0027The subnet %(subnet_id)s must be attached to a router to \u0027"},{"line_number":71,"context_line":"                \u0027enable leak_routes.\u0027,"},{"line_number":72,"context_line":"                subnet_id\u003dsubnet_id)"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"ef03f840_caf4a0d2","line":70,"range":{"start_line":70,"start_character":27,"end_line":70,"end_character":42},"in_reply_to":"b05b8a47_4f4a6401","updated":"2026-08-04 19:16:00.000000000","message":"Done","commit_id":"85a5ef63786da0a6e00c578e0835b337a09f0947"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"9dd3c693a7fdaef018429891606fc5bad60e8396","unresolved":false,"context_lines":[{"line_number":55,"context_line":"    def get_plugin_type(cls):"},{"line_number":56,"context_line":"        return \"bgp-service\""},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def _get_router_port_for_subnet(self, context, subnet_id):"},{"line_number":59,"context_line":"        allocations \u003d port_objects.IPAllocation.get_objects("},{"line_number":60,"context_line":"            context, subnet_id\u003dsubnet_id)"},{"line_number":61,"context_line":"        port_ids \u003d [a.port_id for a in allocations if a.port_id]"},{"line_number":62,"context_line":"        if port_ids:"},{"line_number":63,"context_line":"            ports \u003d port_objects.Port.get_objects("},{"line_number":64,"context_line":"                context, id\u003dport_ids,"},{"line_number":65,"context_line":"                device_owner\u003dn_const.DEVICE_OWNER_ROUTER_INTF)"},{"line_number":66,"context_line":"            if ports:"},{"line_number":67,"context_line":"                return ports[0]"},{"line_number":68,"context_line":"        raise n_exc.BadRequest("},{"line_number":69,"context_line":"            resource\u003d\u0027subnet\u0027,"},{"line_number":70,"context_line":"            msg\u003d\u0027The subnet %(subnet_id)s must be attached to a router to \u0027"},{"line_number":71,"context_line":"                \u0027enable leak_routes.\u0027,"},{"line_number":72,"context_line":"                subnet_id\u003dsubnet_id)"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"34baf68e_29f7881e","line":70,"range":{"start_line":58,"start_character":0,"end_line":70,"end_character":75},"in_reply_to":"c684bc48_381ee682","updated":"2026-08-04 19:16:00.000000000","message":"Done","commit_id":"85a5ef63786da0a6e00c578e0835b337a09f0947"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"9850f157aab41b744a6bc846855173b7363f6abb","unresolved":true,"context_lines":[{"line_number":120,"context_line":"                    \u0027subnets belonging to geneve networks.\u0027)"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"        if leak_routes:"},{"line_number":123,"context_line":"            router_port \u003d self._get_router_port_for_subnet("},{"line_number":124,"context_line":"                context, subnet_id)"},{"line_number":125,"context_line":"            router \u003d router_objects.Router.get_object("},{"line_number":126,"context_line":"                context, id\u003drouter_port.device_id)"}],"source_content_type":"text/x-python","patch_set":3,"id":"14771612_2db9e33e","line":123,"updated":"2026-08-04 15:17:47.000000000","message":"As the only user of this, the above suggested method could join against router as well and do a single query which could be added to the model as a helper method.","commit_id":"85a5ef63786da0a6e00c578e0835b337a09f0947"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"9dd3c693a7fdaef018429891606fc5bad60e8396","unresolved":false,"context_lines":[{"line_number":120,"context_line":"                    \u0027subnets belonging to geneve networks.\u0027)"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"        if leak_routes:"},{"line_number":123,"context_line":"            router_port \u003d self._get_router_port_for_subnet("},{"line_number":124,"context_line":"                context, subnet_id)"},{"line_number":125,"context_line":"            router \u003d router_objects.Router.get_object("},{"line_number":126,"context_line":"                context, id\u003drouter_port.device_id)"}],"source_content_type":"text/x-python","patch_set":3,"id":"ab8a6b3b_ca083216","line":123,"in_reply_to":"14771612_2db9e33e","updated":"2026-08-04 19:16:00.000000000","message":"Done","commit_id":"85a5ef63786da0a6e00c578e0835b337a09f0947"},{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"02a6110a68caf6acccd9df58ad90564b56803327","unresolved":true,"context_lines":[{"line_number":131,"context_line":"                        \u0027gateway set to enable leak_routes.\u0027"},{"line_number":132,"context_line":"                        % {\u0027router_id\u0027: router_port.device_id})"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"        original_leak \u003d original.get(ovn_bgp_apidef.LEAK_ROUTES, False)"},{"line_number":135,"context_line":"        if original_leak \u003d\u003d leak_routes:"},{"line_number":136,"context_line":"            return"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"        if leak_routes:"},{"line_number":139,"context_line":"            LOG.info(\"Subnet %s updated: leak_routes enabled\", subnet_id)"}],"source_content_type":"text/x-python","patch_set":3,"id":"43ab40fc_221b1687","line":136,"range":{"start_line":134,"start_character":0,"end_line":136,"end_character":18},"updated":"2026-07-31 02:34:26.000000000","message":"move this check right after the `KeyError: return` and bailout early, saving from making those DB queries.","commit_id":"85a5ef63786da0a6e00c578e0835b337a09f0947"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"9dd3c693a7fdaef018429891606fc5bad60e8396","unresolved":false,"context_lines":[{"line_number":131,"context_line":"                        \u0027gateway set to enable leak_routes.\u0027"},{"line_number":132,"context_line":"                        % {\u0027router_id\u0027: router_port.device_id})"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"        original_leak \u003d original.get(ovn_bgp_apidef.LEAK_ROUTES, False)"},{"line_number":135,"context_line":"        if original_leak \u003d\u003d leak_routes:"},{"line_number":136,"context_line":"            return"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"        if leak_routes:"},{"line_number":139,"context_line":"            LOG.info(\"Subnet %s updated: leak_routes enabled\", subnet_id)"}],"source_content_type":"text/x-python","patch_set":3,"id":"c6878c77_bd5c5960","line":136,"range":{"start_line":134,"start_character":0,"end_line":136,"end_character":18},"in_reply_to":"43ab40fc_221b1687","updated":"2026-08-04 19:16:00.000000000","message":"Done","commit_id":"85a5ef63786da0a6e00c578e0835b337a09f0947"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"a4e7d2048f82ec0d80f648ee8dd779a1e97e3f48","unresolved":true,"context_lines":[{"line_number":121,"context_line":"                msg\u003d\u0027The leak_routes attribute is only supported on \u0027"},{"line_number":122,"context_line":"                    \u0027subnets belonging to geneve networks.\u0027)"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"        if leak_routes:"},{"line_number":125,"context_line":"            self._validate_gateway_router_for_subnet(context, subnet_id)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"        if leak_routes:"},{"line_number":128,"context_line":"            LOG.info(\"Subnet %s updated: leak_routes enabled\", subnet_id)"},{"line_number":129,"context_line":"        else:"},{"line_number":130,"context_line":"            LOG.info(\"Subnet %s updated: leak_routes disabled\", subnet_id)"}],"source_content_type":"text/x-python","patch_set":4,"id":"a6a47374_a9e92290","line":127,"range":{"start_line":124,"start_character":8,"end_line":127,"end_character":23},"updated":"2026-08-05 07:28:06.000000000","message":"nit: join both","commit_id":"5f443ef542c030fc54d42e3f03a5a5ee6e051df1"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"730bf5268ef434243675d8d3bc277cc406fd2b38","unresolved":false,"context_lines":[{"line_number":121,"context_line":"                msg\u003d\u0027The leak_routes attribute is only supported on \u0027"},{"line_number":122,"context_line":"                    \u0027subnets belonging to geneve networks.\u0027)"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"        if leak_routes:"},{"line_number":125,"context_line":"            self._validate_gateway_router_for_subnet(context, subnet_id)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"        if leak_routes:"},{"line_number":128,"context_line":"            LOG.info(\"Subnet %s updated: leak_routes enabled\", subnet_id)"},{"line_number":129,"context_line":"        else:"},{"line_number":130,"context_line":"            LOG.info(\"Subnet %s updated: leak_routes disabled\", subnet_id)"}],"source_content_type":"text/x-python","patch_set":4,"id":"0f64ab55_3a38dc76","line":127,"range":{"start_line":124,"start_character":8,"end_line":127,"end_character":23},"in_reply_to":"a6a47374_a9e92290","updated":"2026-08-06 20:29:59.000000000","message":"🤦","commit_id":"5f443ef542c030fc54d42e3f03a5a5ee6e051df1"}]}
