)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"60707b26b9708c9d79bb4db9dbef21497868dbaf","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"4a8558e3_63b8910f","updated":"2026-03-06 14:51:43.000000000","message":"few more small comments, otherwise LGTM","commit_id":"56c0c46213c1893f3629ecac80e9cf85fe7b3721"},{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"a9cc3b3ff4f6a389da5eaa298a4dd4990d625500","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"45c8311b_7233ec1b","updated":"2026-03-05 17:20:42.000000000","message":"minor comments","commit_id":"56c0c46213c1893f3629ecac80e9cf85fe7b3721"},{"author":{"_account_id":31291,"name":"Eduardo Olivares","email":"eolivare@redhat.com","username":"eolivare"},"change_message_id":"cc38b1601569b690a32a6a5a57b0e3fa7b8bc407","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"41a44b2a_058d1ebe","updated":"2026-03-05 10:56:19.000000000","message":"recheck","commit_id":"56c0c46213c1893f3629ecac80e9cf85fe7b3721"},{"author":{"_account_id":31291,"name":"Eduardo Olivares","email":"eolivare@redhat.com","username":"eolivare"},"change_message_id":"fdcc615f1db86da2b5a3b63a4055e75598b414ab","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"fd0b425a_52cb6557","updated":"2026-03-10 16:54:52.000000000","message":"It looks like the functional test failures are legit.\nI have looked at it and proposed a WIP with fixes: https://review.opendev.org/c/openstack/neutron/+/979878\n\nIf the fixes work, I will add them to this patch.","commit_id":"5a16bced04acdc4d78f8305e0338b50c79305495"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"e3f149c1996217ac6d727d620493a2298b49df23","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"37920564_e8d3c3bd","updated":"2026-03-06 22:02:51.000000000","message":"recheck functional job didn\u0027t start","commit_id":"5a16bced04acdc4d78f8305e0338b50c79305495"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"212fbf4e722dd48b8e1abbaa8f29fae1be9c93d3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"9dcdadc2_9b3d9cd8","updated":"2026-03-11 14:06:33.000000000","message":"No showstoppers. The TYPE_PHSICAL change was fixed in a previous patch that didn\u0027t make it over to this patch--so it\u0027d be nice to address, since that patch is using TYPE_PHYSICAL and this one isn\u0027t. @jlibosvar should be back Friday","commit_id":"10d0eeaf706b3f61bed9e0cc8ebca126a8f6deed"}],"neutron/services/bgp/commands.py":[{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"212fbf4e722dd48b8e1abbaa8f29fae1be9c93d3","unresolved":true,"context_lines":[{"line_number":66,"context_line":"            ovn_const.OVN_NETTYPE_EXT_ID_KEY) in n_const.TYPE_PHYSICAL]"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"def _get_switch_dhcp_options(nb_idl, switch):"},{"line_number":70,"context_line":"    n_net_id \u003d helpers.get_neutron_id_from_ovn_name(switch)"},{"line_number":71,"context_line":"    for dhcp_opt in nb_idl.tables[\u0027DHCP_Options\u0027].rows.values():"},{"line_number":72,"context_line":"        if dhcp_opt.external_ids.get("},{"line_number":73,"context_line":"                 ovn_const.OVN_NETWORK_ID_EXT_ID_KEY) \u003d\u003d n_net_id:"},{"line_number":74,"context_line":"            yield dhcp_opt"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"def _get_gw_ips_for_switch(nb_idl, switch):"},{"line_number":78,"context_line":"    gw_ips \u003d ["},{"line_number":79,"context_line":"        gw_ip for dhcp_opt in _get_switch_dhcp_options(nb_idl, switch)"},{"line_number":80,"context_line":"        if (gw_ip :\u003d helpers.get_gw_ip_from_dhcp_options("},{"line_number":81,"context_line":"                dhcp_opt)) is not None]"},{"line_number":82,"context_line":"    LOG.debug(\"For logical switch %s, found gateway IPs: %s\","},{"line_number":83,"context_line":"              switch.name, gw_ips)"},{"line_number":84,"context_line":"    return gw_ips"}],"source_content_type":"text/x-python","patch_set":3,"id":"35d6d393_aceb8445","line":81,"range":{"start_line":69,"start_character":0,"end_line":81,"end_character":39},"updated":"2026-03-11 14:06:33.000000000","message":"I assume this change was intentionally included as an unrelated improvement since I don\u0027t see either of these methods being used in this particular patch? No action needed if intentional, just verifying that it was supposed to be in this patch.","commit_id":"5a16bced04acdc4d78f8305e0338b50c79305495"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"24e4067c496c9238719fb7aabff7e33cf067dfac","unresolved":false,"context_lines":[{"line_number":66,"context_line":"            ovn_const.OVN_NETTYPE_EXT_ID_KEY) in n_const.TYPE_PHYSICAL]"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"def _get_switch_dhcp_options(nb_idl, switch):"},{"line_number":70,"context_line":"    n_net_id \u003d helpers.get_neutron_id_from_ovn_name(switch)"},{"line_number":71,"context_line":"    for dhcp_opt in nb_idl.tables[\u0027DHCP_Options\u0027].rows.values():"},{"line_number":72,"context_line":"        if dhcp_opt.external_ids.get("},{"line_number":73,"context_line":"                 ovn_const.OVN_NETWORK_ID_EXT_ID_KEY) \u003d\u003d n_net_id:"},{"line_number":74,"context_line":"            yield dhcp_opt"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"def _get_gw_ips_for_switch(nb_idl, switch):"},{"line_number":78,"context_line":"    gw_ips \u003d ["},{"line_number":79,"context_line":"        gw_ip for dhcp_opt in _get_switch_dhcp_options(nb_idl, switch)"},{"line_number":80,"context_line":"        if (gw_ip :\u003d helpers.get_gw_ip_from_dhcp_options("},{"line_number":81,"context_line":"                dhcp_opt)) is not None]"},{"line_number":82,"context_line":"    LOG.debug(\"For logical switch %s, found gateway IPs: %s\","},{"line_number":83,"context_line":"              switch.name, gw_ips)"},{"line_number":84,"context_line":"    return gw_ips"}],"source_content_type":"text/x-python","patch_set":3,"id":"11cecc8f_54859bba","line":81,"range":{"start_line":69,"start_character":0,"end_line":81,"end_character":39},"in_reply_to":"35d6d393_aceb8445","updated":"2026-03-11 14:18:08.000000000","message":"I see that ReconcileNeutronSwitch is actually called again from the reconciler in this patch, so we can ignore this.","commit_id":"5a16bced04acdc4d78f8305e0338b50c79305495"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"212fbf4e722dd48b8e1abbaa8f29fae1be9c93d3","unresolved":false,"context_lines":[{"line_number":417,"context_line":""},{"line_number":418,"context_line":""},{"line_number":419,"context_line":"class ReconcileGatewayIPCommand(ovs_cmd.BaseCommand):"},{"line_number":420,"context_line":"    def __init__(self, api, dhcp_opt):"},{"line_number":421,"context_line":"        super().__init__(api)"},{"line_number":422,"context_line":"        prefixlen \u003d netaddr.IPNetwork(dhcp_opt.cidr).prefixlen"},{"line_number":423,"context_line":"        self.gw_ip \u003d f\"{dhcp_opt.options[\u0027router\u0027]}/{prefixlen}\""}],"source_content_type":"text/x-python","patch_set":3,"id":"0cda2a89_ef4363a5","line":420,"range":{"start_line":420,"start_character":28,"end_line":420,"end_character":36},"updated":"2026-03-11 14:06:33.000000000","message":"no action needed, as optimizing is perfectly fine when done safely. Just pointing out this is another example of relying on data that possibly can come from outside a txn, and then storing it locally on the command (via the n_net_id derived from it).","commit_id":"5a16bced04acdc4d78f8305e0338b50c79305495"},{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"13406dbc01097e9e67d9187e40819faf71551311","unresolved":true,"context_lines":[{"line_number":445,"context_line":"        # Reading lrp.networks between back-to-back transactions can return"},{"line_number":446,"context_line":"        # stale data from the IDL cache, causing duplicates. addvalue is"},{"line_number":447,"context_line":"        # idempotent for set columns and avoids this race."},{"line_number":448,"context_line":"        lrp.addvalue(\u0027networks\u0027, self.gw_ip)"},{"line_number":449,"context_line":""},{"line_number":450,"context_line":""},{"line_number":451,"context_line":"class ConnectChassisRouterToSwitchCommand(ConnectRouterToSwitchCommand):"}],"source_content_type":"text/x-python","patch_set":5,"id":"f0f0d1cd_2af0c632","line":448,"updated":"2026-03-11 13:28:01.000000000","message":"Dont you still need to check if maybe `gw_ip` does not exists in `networks` already? Or does this operate as a \"add to a set\"?","commit_id":"10d0eeaf706b3f61bed9e0cc8ebca126a8f6deed"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"212fbf4e722dd48b8e1abbaa8f29fae1be9c93d3","unresolved":false,"context_lines":[{"line_number":445,"context_line":"        # Reading lrp.networks between back-to-back transactions can return"},{"line_number":446,"context_line":"        # stale data from the IDL cache, causing duplicates. addvalue is"},{"line_number":447,"context_line":"        # idempotent for set columns and avoids this race."},{"line_number":448,"context_line":"        lrp.addvalue(\u0027networks\u0027, self.gw_ip)"},{"line_number":449,"context_line":""},{"line_number":450,"context_line":""},{"line_number":451,"context_line":"class ConnectChassisRouterToSwitchCommand(ConnectRouterToSwitchCommand):"}],"source_content_type":"text/x-python","patch_set":5,"id":"c1142c82_f15cec2b","line":448,"in_reply_to":"f0f0d1cd_2af0c632","updated":"2026-03-11 14:06:33.000000000","message":"This is handled by ovsdb-server. python-ovs creates a \"mutate\" op for these. See https://datatracker.ietf.org/doc/html/rfc7047#section-5.2.4 for the op, and \u003cmutation\" under https://datatracker.ietf.org/doc/html/rfc7047#section-5.1 \n```\n         If \u003cmutator\u003e is \"insert\", then each of the values in the set in\n         \u003cvalue\u003e is added to \u003ccolumn\u003e if it is not already present.  The\n         required type of \u003cvalue\u003e is slightly relaxed, in that it may\n         have fewer than the minimum number of elements specified by the\n         column\u0027s type.```","commit_id":"10d0eeaf706b3f61bed9e0cc8ebca126a8f6deed"},{"author":{"_account_id":31291,"name":"Eduardo Olivares","email":"eolivare@redhat.com","username":"eolivare"},"change_message_id":"aa9ad4b7a2dc4073e43cac3ab3d6b8232ba8fe6a","unresolved":true,"context_lines":[{"line_number":445,"context_line":"        # Reading lrp.networks between back-to-back transactions can return"},{"line_number":446,"context_line":"        # stale data from the IDL cache, causing duplicates. addvalue is"},{"line_number":447,"context_line":"        # idempotent for set columns and avoids this race."},{"line_number":448,"context_line":"        lrp.addvalue(\u0027networks\u0027, self.gw_ip)"},{"line_number":449,"context_line":""},{"line_number":450,"context_line":""},{"line_number":451,"context_line":"class ConnectChassisRouterToSwitchCommand(ConnectRouterToSwitchCommand):"}],"source_content_type":"text/x-python","patch_set":5,"id":"91ad68dc_5da1d94a","line":448,"in_reply_to":"f0f0d1cd_2af0c632","updated":"2026-03-11 13:58:38.000000000","message":"checking if `gw_ip` exists in `networks` is not necessary because, as you said, it works as an \"add to set\".\n\nRelevant code is here:\nhttps://github.com/openvswitch/ovs/blob/258be7a34303bc708003281eda0c82298c6f96ce/python/ovs/db/idl.py#L1479-L1480","commit_id":"10d0eeaf706b3f61bed9e0cc8ebca126a8f6deed"}],"neutron/services/bgp/constants.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"c22b0608cfa5bd91517ca7370883e368dc4c1ff5","unresolved":true,"context_lines":[{"line_number":41,"context_line":""},{"line_number":42,"context_line":"RELATED_RESOURCE_TAG \u003d \u0027neutron-bgp-related-resource\u0027"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"PROVIDER_NETWORK_TYPES \u003d (n_lib_const.TYPE_FLAT, n_lib_const.TYPE_VLAN)"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"class Enum(enum.Enum):"}],"source_content_type":"text/x-python","patch_set":5,"id":"727c765d_e7b413e7","line":44,"range":{"start_line":44,"start_character":0,"end_line":44,"end_character":22},"updated":"2026-03-11 11:51:47.000000000","message":"nit: we have n_lib_const.TYPE_PHYSICAL","commit_id":"10d0eeaf706b3f61bed9e0cc8ebca126a8f6deed"},{"author":{"_account_id":31291,"name":"Eduardo Olivares","email":"eolivare@redhat.com","username":"eolivare"},"change_message_id":"66a00f7562c40bad6c5b8157ae471007e171c3c3","unresolved":false,"context_lines":[{"line_number":41,"context_line":""},{"line_number":42,"context_line":"RELATED_RESOURCE_TAG \u003d \u0027neutron-bgp-related-resource\u0027"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"PROVIDER_NETWORK_TYPES \u003d (n_lib_const.TYPE_FLAT, n_lib_const.TYPE_VLAN)"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"class Enum(enum.Enum):"}],"source_content_type":"text/x-python","patch_set":5,"id":"78a878d9_c4e85280","line":44,"range":{"start_line":44,"start_character":0,"end_line":44,"end_character":22},"in_reply_to":"5d26e2f3_ddb8c8dd","updated":"2026-03-11 14:52:43.000000000","message":"Done","commit_id":"10d0eeaf706b3f61bed9e0cc8ebca126a8f6deed"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"212fbf4e722dd48b8e1abbaa8f29fae1be9c93d3","unresolved":true,"context_lines":[{"line_number":41,"context_line":""},{"line_number":42,"context_line":"RELATED_RESOURCE_TAG \u003d \u0027neutron-bgp-related-resource\u0027"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"PROVIDER_NETWORK_TYPES \u003d (n_lib_const.TYPE_FLAT, n_lib_const.TYPE_VLAN)"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"class Enum(enum.Enum):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5d26e2f3_ddb8c8dd","line":44,"range":{"start_line":44,"start_character":0,"end_line":44,"end_character":22},"in_reply_to":"727c765d_e7b413e7","updated":"2026-03-11 14:06:33.000000000","message":"I made the same comment in Icb97630615cbcf39f6c04dcb5489449ebaaab351, it must have sneaked into this patch as well.","commit_id":"10d0eeaf706b3f61bed9e0cc8ebca126a8f6deed"}],"neutron/services/bgp/events.py":[{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"a9cc3b3ff4f6a389da5eaa298a4dd4990d625500","unresolved":true,"context_lines":[{"line_number":78,"context_line":"    def match_fn(self, event, row, old):"},{"line_number":79,"context_line":"        if not super().match_fn(event, row, old):"},{"line_number":80,"context_line":"            return False"},{"line_number":81,"context_line":"        net_type \u003d row.external_ids.get(ovn_const.OVN_NETTYPE_EXT_ID_KEY)"},{"line_number":82,"context_line":"        return net_type in constants.PROVIDER_NETWORK_TYPES"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"565b6239_53620793","line":81,"updated":"2026-03-05 17:20:42.000000000","message":"If I understand this correctly, we want to watch for any provider LS which is plugged into a physical network. So if my assumption is correct, then this logic should also check that `OVN_PHYSNET_EXT_ID_KEY` is also part of external_ids in addition to `OVN_NETTYPE_EXT_ID_KEY`","commit_id":"56c0c46213c1893f3629ecac80e9cf85fe7b3721"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"97e2bf6c43906d76e7fd4ec15a90fff7f07ec68e","unresolved":true,"context_lines":[{"line_number":78,"context_line":"    def match_fn(self, event, row, old):"},{"line_number":79,"context_line":"        if not super().match_fn(event, row, old):"},{"line_number":80,"context_line":"            return False"},{"line_number":81,"context_line":"        net_type \u003d row.external_ids.get(ovn_const.OVN_NETTYPE_EXT_ID_KEY)"},{"line_number":82,"context_line":"        return net_type in constants.PROVIDER_NETWORK_TYPES"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"5ea0de02_dbc797da","line":81,"in_reply_to":"565b6239_53620793","updated":"2026-03-05 21:58:20.000000000","message":"Can you please explain for what would we need that?","commit_id":"56c0c46213c1893f3629ecac80e9cf85fe7b3721"},{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"60707b26b9708c9d79bb4db9dbef21497868dbaf","unresolved":false,"context_lines":[{"line_number":78,"context_line":"    def match_fn(self, event, row, old):"},{"line_number":79,"context_line":"        if not super().match_fn(event, row, old):"},{"line_number":80,"context_line":"            return False"},{"line_number":81,"context_line":"        net_type \u003d row.external_ids.get(ovn_const.OVN_NETTYPE_EXT_ID_KEY)"},{"line_number":82,"context_line":"        return net_type in constants.PROVIDER_NETWORK_TYPES"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"c8348547_4fd7db6d","line":81,"in_reply_to":"5ea0de02_dbc797da","updated":"2026-03-06 14:51:43.000000000","message":"We discussed this with Kuba over a chat. Just checking `OVN_NETTYPE_EXT_ID_KEY` is enough because the `PROVIDER_NETWORK_TYPES` only contains flat and vlan types. Other types like geneve would be only part of a LS which does not have localnet and thus \"not a provider network\"","commit_id":"56c0c46213c1893f3629ecac80e9cf85fe7b3721"},{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"a9cc3b3ff4f6a389da5eaa298a4dd4990d625500","unresolved":true,"context_lines":[{"line_number":90,"context_line":"        if not super().match_fn(event, row, old):"},{"line_number":91,"context_line":"            return False"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"        if netaddr.IPNetwork(row.cidr).version \u003d\u003d 6:"},{"line_number":94,"context_line":"            return False"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"        net_id \u003d row.external_ids.get(ovn_const.OVN_NETWORK_ID_EXT_ID_KEY)"}],"source_content_type":"text/x-python","patch_set":2,"id":"2f7faefa_e7104f32","line":93,"range":{"start_line":93,"start_character":50,"end_line":93,"end_character":51},"updated":"2026-03-05 17:20:42.000000000","message":"nit: we have a constant for that :)","commit_id":"56c0c46213c1893f3629ecac80e9cf85fe7b3721"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"97e2bf6c43906d76e7fd4ec15a90fff7f07ec68e","unresolved":false,"context_lines":[{"line_number":90,"context_line":"        if not super().match_fn(event, row, old):"},{"line_number":91,"context_line":"            return False"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"        if netaddr.IPNetwork(row.cidr).version \u003d\u003d 6:"},{"line_number":94,"context_line":"            return False"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"        net_id \u003d row.external_ids.get(ovn_const.OVN_NETWORK_ID_EXT_ID_KEY)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5726783c_d4586e2f","line":93,"range":{"start_line":93,"start_character":50,"end_line":93,"end_character":51},"in_reply_to":"2f7faefa_e7104f32","updated":"2026-03-05 21:58:20.000000000","message":"Done","commit_id":"56c0c46213c1893f3629ecac80e9cf85fe7b3721"},{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"a9cc3b3ff4f6a389da5eaa298a4dd4990d625500","unresolved":true,"context_lines":[{"line_number":93,"context_line":"        if netaddr.IPNetwork(row.cidr).version \u003d\u003d 6:"},{"line_number":94,"context_line":"            return False"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"        net_id \u003d row.external_ids.get(ovn_const.OVN_NETWORK_ID_EXT_ID_KEY)"},{"line_number":97,"context_line":"        try:"},{"line_number":98,"context_line":"            switch \u003d self.reconciler.nb_api.lookup("},{"line_number":99,"context_line":"                \u0027Logical_Switch\u0027, f\"neutron-{net_id}\")"},{"line_number":100,"context_line":"        except idlutils.RowNotFound:"},{"line_number":101,"context_line":"            LOG.warning(\"Switch neutron-%s not found\", net_id)"},{"line_number":102,"context_line":"            return False"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"        net_type \u003d switch.external_ids.get(ovn_const.OVN_NETTYPE_EXT_ID_KEY)"}],"source_content_type":"text/x-python","patch_set":2,"id":"50fe5d92_3b23cdce","line":101,"range":{"start_line":96,"start_character":0,"end_line":101,"end_character":62},"updated":"2026-03-05 17:20:42.000000000","message":"nit: `get` will return None if net_id is not part of external_ids and then the log would say `Switch neutron-None not found`.\nI would make getting a proper `net_id` its own condition that returns False if not present.","commit_id":"56c0c46213c1893f3629ecac80e9cf85fe7b3721"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"97e2bf6c43906d76e7fd4ec15a90fff7f07ec68e","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        if netaddr.IPNetwork(row.cidr).version \u003d\u003d 6:"},{"line_number":94,"context_line":"            return False"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"        net_id \u003d row.external_ids.get(ovn_const.OVN_NETWORK_ID_EXT_ID_KEY)"},{"line_number":97,"context_line":"        try:"},{"line_number":98,"context_line":"            switch \u003d self.reconciler.nb_api.lookup("},{"line_number":99,"context_line":"                \u0027Logical_Switch\u0027, f\"neutron-{net_id}\")"},{"line_number":100,"context_line":"        except idlutils.RowNotFound:"},{"line_number":101,"context_line":"            LOG.warning(\"Switch neutron-%s not found\", net_id)"},{"line_number":102,"context_line":"            return False"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"        net_type \u003d switch.external_ids.get(ovn_const.OVN_NETTYPE_EXT_ID_KEY)"}],"source_content_type":"text/x-python","patch_set":2,"id":"72c56299_cb4fdef9","line":101,"range":{"start_line":96,"start_character":0,"end_line":101,"end_character":62},"in_reply_to":"50fe5d92_3b23cdce","updated":"2026-03-05 21:58:20.000000000","message":"Done","commit_id":"56c0c46213c1893f3629ecac80e9cf85fe7b3721"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"212fbf4e722dd48b8e1abbaa8f29fae1be9c93d3","unresolved":true,"context_lines":[{"line_number":32,"context_line":"}"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"class BGPResourceEvent(row_event.RowEvent):"},{"line_number":36,"context_line":"    RESOURCE: typing.ClassVar["},{"line_number":37,"context_line":"        constants.BGPReconcilerResource | None] \u003d None"},{"line_number":38,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"a4338144_dea67a75","line":35,"range":{"start_line":35,"start_character":6,"end_line":35,"end_character":22},"updated":"2026-03-11 14:06:33.000000000","message":"nittiest of naming nits: Since what you do with resources is to reconcile them, and the run() is defined here and not in the subclasses, it might be clearer to make this BGPReconcileEvent or something just to make clear that the invisible run() is going to call reconcile(). If you\u0027re respinning anyway for the TYPE_PHYSICAL change. No action needed if you disagree as this is just personal preference. 😊","commit_id":"10d0eeaf706b3f61bed9e0cc8ebca126a8f6deed"},{"author":{"_account_id":31291,"name":"Eduardo Olivares","email":"eolivare@redhat.com","username":"eolivare"},"change_message_id":"66a00f7562c40bad6c5b8157ae471007e171c3c3","unresolved":false,"context_lines":[{"line_number":32,"context_line":"}"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"class BGPResourceEvent(row_event.RowEvent):"},{"line_number":36,"context_line":"    RESOURCE: typing.ClassVar["},{"line_number":37,"context_line":"        constants.BGPReconcilerResource | None] \u003d None"},{"line_number":38,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"a1f8bfdb_f6c52579","line":35,"range":{"start_line":35,"start_character":6,"end_line":35,"end_character":22},"in_reply_to":"a4338144_dea67a75","updated":"2026-03-11 14:52:43.000000000","message":"Done","commit_id":"10d0eeaf706b3f61bed9e0cc8ebca126a8f6deed"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"212fbf4e722dd48b8e1abbaa8f29fae1be9c93d3","unresolved":true,"context_lines":[{"line_number":96,"context_line":"        net_id \u003d row.external_ids.get(ovn_const.OVN_NETWORK_ID_EXT_ID_KEY)"},{"line_number":97,"context_line":"        try:"},{"line_number":98,"context_line":"            switch \u003d self.reconciler.nb_api.lookup("},{"line_number":99,"context_line":"                \u0027Logical_Switch\u0027, f\"neutron-{net_id}\")"},{"line_number":100,"context_line":"        except idlutils.RowNotFound:"},{"line_number":101,"context_line":"            LOG.warning(\"Switch neutron-%s not found\", net_id)"},{"line_number":102,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":5,"id":"c31bcb0c_3b72c565","line":99,"range":{"start_line":99,"start_character":34,"end_line":99,"end_character":53},"updated":"2026-03-11 14:06:33.000000000","message":"nit: `neutron.common.ovn.utils.ovn_name(net_id)`","commit_id":"10d0eeaf706b3f61bed9e0cc8ebca126a8f6deed"},{"author":{"_account_id":31291,"name":"Eduardo Olivares","email":"eolivare@redhat.com","username":"eolivare"},"change_message_id":"66a00f7562c40bad6c5b8157ae471007e171c3c3","unresolved":false,"context_lines":[{"line_number":96,"context_line":"        net_id \u003d row.external_ids.get(ovn_const.OVN_NETWORK_ID_EXT_ID_KEY)"},{"line_number":97,"context_line":"        try:"},{"line_number":98,"context_line":"            switch \u003d self.reconciler.nb_api.lookup("},{"line_number":99,"context_line":"                \u0027Logical_Switch\u0027, f\"neutron-{net_id}\")"},{"line_number":100,"context_line":"        except idlutils.RowNotFound:"},{"line_number":101,"context_line":"            LOG.warning(\"Switch neutron-%s not found\", net_id)"},{"line_number":102,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":5,"id":"c09a788f_70d5a5ef","line":99,"range":{"start_line":99,"start_character":34,"end_line":99,"end_character":53},"in_reply_to":"c31bcb0c_3b72c565","updated":"2026-03-11 14:52:43.000000000","message":"Done","commit_id":"10d0eeaf706b3f61bed9e0cc8ebca126a8f6deed"}],"neutron/services/bgp/reconciler.py":[{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"60707b26b9708c9d79bb4db9dbef21497868dbaf","unresolved":true,"context_lines":[{"line_number":76,"context_line":"        else:"},{"line_number":77,"context_line":"            LOG.info(\"Full BGP topology synchronization already in progress\")"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    def reconcile(self, action, resource, trigger):"},{"line_number":80,"context_line":"        try:"},{"line_number":81,"context_line":"            self.resource_map[action][resource](trigger)"},{"line_number":82,"context_line":"        except KeyError:"}],"source_content_type":"text/x-python","patch_set":2,"id":"f9ec7ffd_6666bc60","line":79,"range":{"start_line":79,"start_character":24,"end_line":79,"end_character":30},"updated":"2026-03-06 14:51:43.000000000","message":"Will the action ever be something else than `reconcile`? If not, why force the caller always pass the `reconcile`. It should be assumed that a `BGPTopologyReconciler.reconcile(...)` call will just reconcile :)","commit_id":"56c0c46213c1893f3629ecac80e9cf85fe7b3721"},{"author":{"_account_id":34271,"name":"Miro Tomaska","display_name":"Miro Tomaska","email":"mtomaska@redhat.com","username":"mtomaska"},"change_message_id":"430862e24da03dcba1b5926559c7a4bbe4e876f3","unresolved":false,"context_lines":[{"line_number":76,"context_line":"        else:"},{"line_number":77,"context_line":"            LOG.info(\"Full BGP topology synchronization already in progress\")"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    def reconcile(self, action, resource, trigger):"},{"line_number":80,"context_line":"        try:"},{"line_number":81,"context_line":"            self.resource_map[action][resource](trigger)"},{"line_number":82,"context_line":"        except KeyError:"}],"source_content_type":"text/x-python","patch_set":2,"id":"5eb2ce0d_19749199","line":79,"range":{"start_line":79,"start_character":24,"end_line":79,"end_character":30},"in_reply_to":"404ed99a_acff0b8a","updated":"2026-03-06 15:40:22.000000000","message":"Acknowledged","commit_id":"56c0c46213c1893f3629ecac80e9cf85fe7b3721"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"fec994a9ce060cdf2bb796c0f11c8c89ed109a9a","unresolved":true,"context_lines":[{"line_number":76,"context_line":"        else:"},{"line_number":77,"context_line":"            LOG.info(\"Full BGP topology synchronization already in progress\")"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    def reconcile(self, action, resource, trigger):"},{"line_number":80,"context_line":"        try:"},{"line_number":81,"context_line":"            self.resource_map[action][resource](trigger)"},{"line_number":82,"context_line":"        except KeyError:"}],"source_content_type":"text/x-python","patch_set":2,"id":"404ed99a_acff0b8a","line":79,"range":{"start_line":79,"start_character":24,"end_line":79,"end_character":30},"in_reply_to":"de75362b_374bdb88","updated":"2026-03-06 15:29:49.000000000","message":"I pushed a WIP patch https://review.opendev.org/c/openstack/neutron/+/979286/1/neutron/services/bgp/reconciler.py that does exactly that - I hope it is more clear with it, I know right now it\u0027s confusing.","commit_id":"56c0c46213c1893f3629ecac80e9cf85fe7b3721"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"b4202fc44e1d649d28a354d02787e30b94315268","unresolved":true,"context_lines":[{"line_number":76,"context_line":"        else:"},{"line_number":77,"context_line":"            LOG.info(\"Full BGP topology synchronization already in progress\")"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    def reconcile(self, action, resource, trigger):"},{"line_number":80,"context_line":"        try:"},{"line_number":81,"context_line":"            self.resource_map[action][resource](trigger)"},{"line_number":82,"context_line":"        except KeyError:"}],"source_content_type":"text/x-python","patch_set":2,"id":"de75362b_374bdb88","line":79,"range":{"start_line":79,"start_character":24,"end_line":79,"end_character":30},"in_reply_to":"f9ec7ffd_6666bc60","updated":"2026-03-06 15:28:04.000000000","message":"Yes, it will also be a \u0027delete\u0027 action","commit_id":"56c0c46213c1893f3629ecac80e9cf85fe7b3721"}],"neutron/tests/functional/services/bgp/test_events.py":[{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"aa3325fbfd9fc13f49178956877296f27ed8ed11","unresolved":true,"context_lines":[{"line_number":32,"context_line":"        super().setUp()"},{"line_number":33,"context_line":"        self.reconciler \u003d mock.Mock()"},{"line_number":34,"context_line":"        self.event \u003d self._create_event()"},{"line_number":35,"context_line":"        self.event.api \u003d self.nb_api"},{"line_number":36,"context_line":"        self.nb_api.idl.notify_handler.watch_event(self.event)"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def _create_event(self):"}],"source_content_type":"text/x-python","patch_set":1,"id":"e1d655c1_c3bb9b98","line":35,"updated":"2026-02-27 15:18:59.000000000","message":"bad AI","commit_id":"4683dcec5375cb702dd0c584adede86bf5478aae"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"706509dce0c208f0baac6ccdf05059ed5e164e6c","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        super().setUp()"},{"line_number":33,"context_line":"        self.reconciler \u003d mock.Mock()"},{"line_number":34,"context_line":"        self.event \u003d self._create_event()"},{"line_number":35,"context_line":"        self.event.api \u003d self.nb_api"},{"line_number":36,"context_line":"        self.nb_api.idl.notify_handler.watch_event(self.event)"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def _create_event(self):"}],"source_content_type":"text/x-python","patch_set":1,"id":"abee6ea6_3a3f836a","line":35,"in_reply_to":"e1d655c1_c3bb9b98","updated":"2026-02-27 15:36:22.000000000","message":"Done","commit_id":"4683dcec5375cb702dd0c584adede86bf5478aae"}]}
