)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"ecab9a28ae44b8c025de5782a1828a80e165b773","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"b145c3f8_db24d8a3","updated":"2025-11-14 20:30:26.000000000","message":"Comments addressed.","commit_id":"97f14d185a445c22efa2d1ac3f058c9fabf10172"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"1692e8bc1ee5ce20aca16972e353c6ee6b48a6b6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"57d576a9_8cb36a1c","updated":"2025-11-27 16:42:08.000000000","message":"comments addressed, PTAL","commit_id":"9964607e9698c53b730cb4362ca3d45899e53a9a"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fcadabe433ab347861ec07b6ec5874a83b5c7006","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"9a474c66_4a7b7bc5","updated":"2025-12-01 12:29:18.000000000","message":"recheck","commit_id":"9964607e9698c53b730cb4362ca3d45899e53a9a"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"6c66df83f1a3ee57a665d4c2fb96deb02c818232","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":9,"id":"68f31e3a_7e37c5f2","updated":"2026-01-15 21:26:51.000000000","message":"A demo or interactive review would help raise my confidence to a +2","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"dbbd1e94279fa729b187d0b028fe0b6b7bc7b5e1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"ad482252_8034e85a","updated":"2026-01-06 18:15:21.000000000","message":"First pass. Overall looks good but I need to sit down and take a focused look at ironic_networking.py","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"db419fee6ab6872074cafa89fc7934b17b56ce89","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"e1b952f1_60a2e081","updated":"2026-01-19 14:41:00.000000000","message":"Some comments inline. Mostly minor and can be addressed in a follow-up, but one thing that worries me is lack of exception propagation in the tenant network handling.","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"c7e4f47b_1ba44166","in_reply_to":"68f31e3a_7e37c5f2","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"2fa3d95546398907f71e7f712f006edf36bd34d0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"56f6b7fd_f72fb3a9","updated":"2026-01-20 22:19:56.000000000","message":"Comments addressed.  PTAL.","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"8146f181957d7de88ef4ff026882a19cebf7ecde","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"3bbc1dd3_cbd5bcb8","updated":"2026-01-26 18:33:13.000000000","message":"I\u0027m good with this as long as we cleanup the exception handling and NoopNetwork listing.","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"e59cd27044d97f6a206bb199129c3f852700f696","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":10,"id":"9a9675aa_c8aaea8c","updated":"2026-01-20 23:17:44.000000000","message":"Same comment as before: pretty sure I could get this to a +2 with a sync review jam","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":10,"id":"10fa7ea7_d56d019f","updated":"2026-01-26 19:24:38.000000000","message":"There are a couple of things in here that are borderline for follow-ups, but I\u0027m not going to make you wait longer to land this.\n\nPlease ensure we always re-raise exception and avoid `except Exception` if possible.","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"d4546172_91cade3b","updated":"2026-01-28 14:43:59.000000000","message":"comments addressed.  PTAL","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"5798150a_49b3cf52","in_reply_to":"10fa7ea7_d56d019f","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"f651a448_1c332529","in_reply_to":"9a9675aa_c8aaea8c","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"7346b598af7ad72efcc3f0012f23f16270dbb790","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"98c37313_58dc2abd","updated":"2026-01-29 18:48:50.000000000","message":"The +2 is with the understanding the couple minor items will be followed up.","commit_id":"0da5f50c2ce8ef6a3c3f16d5c4489d38b5e4053f"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"28c0b8dd7dd2988f45e0e4cd0179eb32e577bb2a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"344c2c50_4d95df72","updated":"2026-01-30 19:31:05.000000000","message":"comments addressed.  PTAL.","commit_id":"0da5f50c2ce8ef6a3c3f16d5c4489d38b5e4053f"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"83a0c2c47e9e6dd6e2ea0d89c950bfb141a418e0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"2b5ece53_3d59131e","updated":"2026-02-03 10:24:50.000000000","message":"Treat my +1 as non-blocking, I\u0027m fine with any updates from my feedback being a follow-up.","commit_id":"c5f75a924c4e7b90f581a2722da9cc49bacc61bc"},{"author":{"_account_id":23851,"name":"Riccardo Pittau","email":"elfosardo@gmail.com","username":"elfosardo"},"change_message_id":"17a3c9f039610ccc22e2fc998e4aba3ade911c79","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"bd49e083_b4ab7756","updated":"2026-02-03 13:26:55.000000000","message":"follow up needed as mentioned before already","commit_id":"c5f75a924c4e7b90f581a2722da9cc49bacc61bc"}],"ironic/drivers/generic.py":[{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"8146f181957d7de88ef4ff026882a19cebf7ecde","unresolved":true,"context_lines":[{"line_number":65,"context_line":"    def supported_network_interfaces(self):"},{"line_number":66,"context_line":"        \"\"\"List of supported network interfaces.\"\"\""},{"line_number":67,"context_line":"        return [flat_net.FlatNetwork, neutron.NeutronNetwork,"},{"line_number":68,"context_line":"                noop_net.NoopNetwork,"},{"line_number":69,"context_line":"                ironic_networking.IronicNetworking]"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":10,"id":"7bc1cc9f_7645202d","line":68,"updated":"2026-01-26 18:33:13.000000000","message":"Order wise, NoopNetwork likely needs to be the last entry. Some folks don\u0027t explicitly use default_network_interface.","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":65,"context_line":"    def supported_network_interfaces(self):"},{"line_number":66,"context_line":"        \"\"\"List of supported network interfaces.\"\"\""},{"line_number":67,"context_line":"        return [flat_net.FlatNetwork, neutron.NeutronNetwork,"},{"line_number":68,"context_line":"                noop_net.NoopNetwork,"},{"line_number":69,"context_line":"                ironic_networking.IronicNetworking]"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":10,"id":"4f2423bb_aa84ac07","line":68,"in_reply_to":"7bc1cc9f_7645202d","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":66,"context_line":"        \"\"\"List of supported network interfaces.\"\"\""},{"line_number":67,"context_line":"        return [flat_net.FlatNetwork, neutron.NeutronNetwork,"},{"line_number":68,"context_line":"                noop_net.NoopNetwork,"},{"line_number":69,"context_line":"                ironic_networking.IronicNetworking]"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"    @property"},{"line_number":72,"context_line":"    def supported_raid_interfaces(self):"}],"source_content_type":"text/x-python","patch_set":10,"id":"c9b18a35_e3bcaa36","line":69,"updated":"2026-01-26 19:24:38.000000000","message":"There seems to be discussion that there could be value to swap noop_net.NoopNetwork and ironic_networking.IronicNetworking","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        \"\"\"List of supported network interfaces.\"\"\""},{"line_number":67,"context_line":"        return [flat_net.FlatNetwork, neutron.NeutronNetwork,"},{"line_number":68,"context_line":"                noop_net.NoopNetwork,"},{"line_number":69,"context_line":"                ironic_networking.IronicNetworking]"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"    @property"},{"line_number":72,"context_line":"    def supported_raid_interfaces(self):"}],"source_content_type":"text/x-python","patch_set":10,"id":"be77230d_1d72842b","line":69,"in_reply_to":"c9b18a35_e3bcaa36","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"}],"ironic/drivers/modules/network/ironic_networking.py":[{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"0da87c480885f35041464671820f9fdad3240e38","unresolved":true,"context_lines":[{"line_number":1226,"context_line":"                    {\u0027network_type\u0027: network_type, \u0027port\u0027: port.uuid,"},{"line_number":1227,"context_line":"                     \u0027err\u0027: exc}"},{"line_number":1228,"context_line":"                )"},{"line_number":1229,"context_line":"                raise exception.NetworkError("},{"line_number":1230,"context_line":"                    _(\"Failed to reset %(network_type)s network for port \""},{"line_number":1231,"context_line":"                      \"%(port)s: %(err)s\")"},{"line_number":1232,"context_line":"                    % {\u0027network_type\u0027: network_type, \u0027port\u0027: port.uuid,"}],"source_content_type":"text/x-python","patch_set":1,"id":"86bbcbb9_c1d83ae6","line":1229,"range":{"start_line":1229,"start_character":0,"end_line":1229,"end_character":45},"updated":"2025-11-11 08:00:56.000000000","message":"Is there a reason we want to fail fast during the clean-up as well, instead of, say, aggregating the errors?","commit_id":"d62b41a598be3aafcb57dfc0ab4b794e95b29341"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"ecab9a28ae44b8c025de5782a1828a80e165b773","unresolved":false,"context_lines":[{"line_number":1226,"context_line":"                    {\u0027network_type\u0027: network_type, \u0027port\u0027: port.uuid,"},{"line_number":1227,"context_line":"                     \u0027err\u0027: exc}"},{"line_number":1228,"context_line":"                )"},{"line_number":1229,"context_line":"                raise exception.NetworkError("},{"line_number":1230,"context_line":"                    _(\"Failed to reset %(network_type)s network for port \""},{"line_number":1231,"context_line":"                      \"%(port)s: %(err)s\")"},{"line_number":1232,"context_line":"                    % {\u0027network_type\u0027: network_type, \u0027port\u0027: port.uuid,"}],"source_content_type":"text/x-python","patch_set":1,"id":"c7936f16_89e66575","line":1229,"range":{"start_line":1229,"start_character":0,"end_line":1229,"end_character":45},"in_reply_to":"86bbcbb9_c1d83ae6","updated":"2025-11-14 20:30:26.000000000","message":"That\u0027s a good point. Updated","commit_id":"d62b41a598be3aafcb57dfc0ab4b794e95b29341"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"41fae8cc01b41ddf8488d3cf380b9749185653a7","unresolved":true,"context_lines":[{"line_number":314,"context_line":""},{"line_number":315,"context_line":"        # Validate that local_link_connection has required fields"},{"line_number":316,"context_line":"        if not port.local_link_connection:"},{"line_number":317,"context_line":"            # TODO(alegacy): This should probably result in an error since"},{"line_number":318,"context_line":"            # the operator clearly wants to configure a switchport but we"},{"line_number":319,"context_line":"            # do not know which one.  This can happen when the node is"},{"line_number":320,"context_line":"            # initially enrolled if the switchport info is provided but"}],"source_content_type":"text/x-python","patch_set":4,"id":"dcc8a59d_d9b7fb1e","line":317,"updated":"2025-12-04 18:42:16.000000000","message":"Yeah, I\u0027d change this over to an exception since we can\u0027t schedule or use a port without backing configuration.","commit_id":"26dffef8cb59f1671c1564cbee32c8217f9a20b3"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"c97c21ad1129aee573c8176c12f16bc9cf3b6601","unresolved":false,"context_lines":[{"line_number":314,"context_line":""},{"line_number":315,"context_line":"        # Validate that local_link_connection has required fields"},{"line_number":316,"context_line":"        if not port.local_link_connection:"},{"line_number":317,"context_line":"            # TODO(alegacy): This should probably result in an error since"},{"line_number":318,"context_line":"            # the operator clearly wants to configure a switchport but we"},{"line_number":319,"context_line":"            # do not know which one.  This can happen when the node is"},{"line_number":320,"context_line":"            # initially enrolled if the switchport info is provided but"}],"source_content_type":"text/x-python","patch_set":4,"id":"03bed823_b605eaff","line":317,"in_reply_to":"8f972e34_3c677007","updated":"2025-12-07 21:27:30.000000000","message":"fixed","commit_id":"26dffef8cb59f1671c1564cbee32c8217f9a20b3"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"3239f3381257a73f2107a5a0e6cabbaa179b054d","unresolved":true,"context_lines":[{"line_number":314,"context_line":""},{"line_number":315,"context_line":"        # Validate that local_link_connection has required fields"},{"line_number":316,"context_line":"        if not port.local_link_connection:"},{"line_number":317,"context_line":"            # TODO(alegacy): This should probably result in an error since"},{"line_number":318,"context_line":"            # the operator clearly wants to configure a switchport but we"},{"line_number":319,"context_line":"            # do not know which one.  This can happen when the node is"},{"line_number":320,"context_line":"            # initially enrolled if the switchport info is provided but"}],"source_content_type":"text/x-python","patch_set":4,"id":"8f972e34_3c677007","line":317,"in_reply_to":"dcc8a59d_d9b7fb1e","updated":"2025-12-04 18:47:24.000000000","message":"ok, but as I stated in the TODO comment... we\u0027d need to differentiate cases where inspection hasn\u0027t occurred yet because that shouldn\u0027t be an error.  If inspection occurred then LLDP `should` have been obtained and then we can make that an error.  \n\nIs there an easy way to tell (from here) that inspection has run and therefore we should have local_link_connection info for all ports?","commit_id":"26dffef8cb59f1671c1564cbee32c8217f9a20b3"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"6c66df83f1a3ee57a665d4c2fb96deb02c818232","unresolved":true,"context_lines":[{"line_number":98,"context_line":"class IronicNetworking(base.NetworkInterface):"},{"line_number":99,"context_line":"    \"\"\"Ironic Networking network interface."},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    This network interface is designed for experimental standalone Ironic"},{"line_number":102,"context_line":"    deployments where network configuration is either handled externally"},{"line_number":103,"context_line":"    or not required. All methods are implemented as no-ops, allowing Ironic"},{"line_number":104,"context_line":"    to operate without performing any network-related actions."}],"source_content_type":"text/x-python","patch_set":9,"id":"40a67ffb_0ab348ae","line":101,"updated":"2026-01-15 21:26:51.000000000","message":"experimental? Can we remove this adjective","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"ed5dc8c286ef7b0cd1136fb33c89cb44dc3f89e7","unresolved":true,"context_lines":[{"line_number":98,"context_line":"class IronicNetworking(base.NetworkInterface):"},{"line_number":99,"context_line":"    \"\"\"Ironic Networking network interface."},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    This network interface is designed for experimental standalone Ironic"},{"line_number":102,"context_line":"    deployments where network configuration is either handled externally"},{"line_number":103,"context_line":"    or not required. All methods are implemented as no-ops, allowing Ironic"},{"line_number":104,"context_line":"    to operate without performing any network-related actions."}],"source_content_type":"text/x-python","patch_set":9,"id":"87a54ac3_ab83216b","line":101,"in_reply_to":"40a67ffb_0ab348ae","updated":"2026-01-16 16:38:59.000000000","message":"@jay@jvf.cc rather than re-spin it just for this, I\u0027ll circle back and fix this with a another patch later if that\u0027s ok.","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"2a65f224cd574869c1b62d31422d71fc786566d0","unresolved":true,"context_lines":[{"line_number":98,"context_line":"class IronicNetworking(base.NetworkInterface):"},{"line_number":99,"context_line":"    \"\"\"Ironic Networking network interface."},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    This network interface is designed for experimental standalone Ironic"},{"line_number":102,"context_line":"    deployments where network configuration is either handled externally"},{"line_number":103,"context_line":"    or not required. All methods are implemented as no-ops, allowing Ironic"},{"line_number":104,"context_line":"    to operate without performing any network-related actions."}],"source_content_type":"text/x-python","patch_set":9,"id":"88e97ed3_8b26f831","line":101,"in_reply_to":"87a54ac3_ab83216b","updated":"2026-01-18 17:00:02.000000000","message":"for stuff like this that is always fine by me :) Thanks!","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"2fa3d95546398907f71e7f712f006edf36bd34d0","unresolved":false,"context_lines":[{"line_number":98,"context_line":"class IronicNetworking(base.NetworkInterface):"},{"line_number":99,"context_line":"    \"\"\"Ironic Networking network interface."},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    This network interface is designed for experimental standalone Ironic"},{"line_number":102,"context_line":"    deployments where network configuration is either handled externally"},{"line_number":103,"context_line":"    or not required. All methods are implemented as no-ops, allowing Ironic"},{"line_number":104,"context_line":"    to operate without performing any network-related actions."}],"source_content_type":"text/x-python","patch_set":9,"id":"f1175692_657b69d5","line":101,"in_reply_to":"88e97ed3_8b26f831","updated":"2026-01-20 22:19:56.000000000","message":"Done","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"db419fee6ab6872074cafa89fc7934b17b56ce89","unresolved":true,"context_lines":[{"line_number":148,"context_line":"        :raises: MissingParameterValue if switchport or LAG schema"},{"line_number":149,"context_line":"                 is not available."},{"line_number":150,"context_line":"        \"\"\""},{"line_number":151,"context_line":"        if not self.switchport_schema:"},{"line_number":152,"context_line":"            raise exception.MissingParameterValue("},{"line_number":153,"context_line":"                _(\"Switchport validation schema not available for \""},{"line_number":154,"context_line":"                  \"ironic-networking network interface\"))"}],"source_content_type":"text/x-python","patch_set":9,"id":"d41ea79c_c53e9ef5","line":151,"updated":"2026-01-19 14:41:00.000000000","message":"Why not check this on start-up and then drop all the checks on `if self.switchport_schema` (same for LAG)?","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"2fa3d95546398907f71e7f712f006edf36bd34d0","unresolved":false,"context_lines":[{"line_number":148,"context_line":"        :raises: MissingParameterValue if switchport or LAG schema"},{"line_number":149,"context_line":"                 is not available."},{"line_number":150,"context_line":"        \"\"\""},{"line_number":151,"context_line":"        if not self.switchport_schema:"},{"line_number":152,"context_line":"            raise exception.MissingParameterValue("},{"line_number":153,"context_line":"                _(\"Switchport validation schema not available for \""},{"line_number":154,"context_line":"                  \"ironic-networking network interface\"))"}],"source_content_type":"text/x-python","patch_set":9,"id":"35a3ee98_c25ec84a","line":151,"in_reply_to":"d41ea79c_c53e9ef5","updated":"2026-01-20 22:19:56.000000000","message":"Done","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"db419fee6ab6872074cafa89fc7934b17b56ce89","unresolved":true,"context_lines":[{"line_number":217,"context_line":"            if vlan_part.startswith(\u0027native_vlan\u003d\u0027):"},{"line_number":218,"context_line":"                native_vlan \u003d int(vlan_part.split(\u0027\u003d\u0027, 1)[1])"},{"line_number":219,"context_line":"            else:"},{"line_number":220,"context_line":"                native_vlan \u003d None"},{"line_number":221,"context_line":"        except Exception:"},{"line_number":222,"context_line":"            LOG.warning(\"Invalid %s network value: %s\","},{"line_number":223,"context_line":"                        network_type, network_value)"}],"source_content_type":"text/x-python","patch_set":9,"id":"62bae047_c34382f3","line":220,"updated":"2026-01-19 14:41:00.000000000","message":"Shouldn\u0027t this be an error instead if vlan_part is not empty?","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"2fa3d95546398907f71e7f712f006edf36bd34d0","unresolved":false,"context_lines":[{"line_number":217,"context_line":"            if vlan_part.startswith(\u0027native_vlan\u003d\u0027):"},{"line_number":218,"context_line":"                native_vlan \u003d int(vlan_part.split(\u0027\u003d\u0027, 1)[1])"},{"line_number":219,"context_line":"            else:"},{"line_number":220,"context_line":"                native_vlan \u003d None"},{"line_number":221,"context_line":"        except Exception:"},{"line_number":222,"context_line":"            LOG.warning(\"Invalid %s network value: %s\","},{"line_number":223,"context_line":"                        network_type, network_value)"}],"source_content_type":"text/x-python","patch_set":9,"id":"a6ae2b8c_1f200cbd","line":220,"in_reply_to":"62bae047_c34382f3","updated":"2026-01-20 22:19:56.000000000","message":"Done","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"db419fee6ab6872074cafa89fc7934b17b56ce89","unresolved":true,"context_lines":[{"line_number":219,"context_line":"            else:"},{"line_number":220,"context_line":"                native_vlan \u003d None"},{"line_number":221,"context_line":"        except Exception:"},{"line_number":222,"context_line":"            LOG.warning(\"Invalid %s network value: %s\","},{"line_number":223,"context_line":"                        network_type, network_value)"},{"line_number":224,"context_line":"            return None, None, None"},{"line_number":225,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"0fdc5ae7_355f282b","line":222,"updated":"2026-01-19 14:41:00.000000000","message":"Any reason not to have this as a fatal error? Reaching this line may mean invalid user input.","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"2fa3d95546398907f71e7f712f006edf36bd34d0","unresolved":false,"context_lines":[{"line_number":219,"context_line":"            else:"},{"line_number":220,"context_line":"                native_vlan \u003d None"},{"line_number":221,"context_line":"        except Exception:"},{"line_number":222,"context_line":"            LOG.warning(\"Invalid %s network value: %s\","},{"line_number":223,"context_line":"                        network_type, network_value)"},{"line_number":224,"context_line":"            return None, None, None"},{"line_number":225,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"32274b1c_aeea961f","line":222,"in_reply_to":"0fdc5ae7_355f282b","updated":"2026-01-20 22:19:56.000000000","message":"Done","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"db419fee6ab6872074cafa89fc7934b17b56ce89","unresolved":true,"context_lines":[{"line_number":226,"context_line":"        LOG.debug("},{"line_number":227,"context_line":"            \"Called _get_network_mode_and_vlan with node\u003d%s, \""},{"line_number":228,"context_line":"            \"network_type\u003d%s; returning mode\u003d%s, native_vlan\u003d%s, \""},{"line_number":229,"context_line":"            \"allowed_vlans\u003d%s from value\u003d\u0027%s\u0027\","},{"line_number":230,"context_line":"            getattr(task.node, \u0027uuid\u0027, None), network_type, mode,"},{"line_number":231,"context_line":"            native_vlan, allowed_vlans, network_value)"},{"line_number":232,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"0d0281a0_5fd291f9","line":229,"updated":"2026-01-19 14:41:00.000000000","message":"nit: when there are so many values, we tend to use the dict based format (passing `%(mode)s` etc and then providing a dict).","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"2fa3d95546398907f71e7f712f006edf36bd34d0","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        LOG.debug("},{"line_number":227,"context_line":"            \"Called _get_network_mode_and_vlan with node\u003d%s, \""},{"line_number":228,"context_line":"            \"network_type\u003d%s; returning mode\u003d%s, native_vlan\u003d%s, \""},{"line_number":229,"context_line":"            \"allowed_vlans\u003d%s from value\u003d\u0027%s\u0027\","},{"line_number":230,"context_line":"            getattr(task.node, \u0027uuid\u0027, None), network_type, mode,"},{"line_number":231,"context_line":"            native_vlan, allowed_vlans, network_value)"},{"line_number":232,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"15bcc5ae_7d59bace","line":229,"in_reply_to":"0d0281a0_5fd291f9","updated":"2026-01-20 22:19:56.000000000","message":"Done","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"db419fee6ab6872074cafa89fc7934b17b56ce89","unresolved":true,"context_lines":[{"line_number":277,"context_line":"        # cleaning or rescuing if we require ports to be present and"},{"line_number":278,"context_line":"        # configured.  Needs more thought.  Maybe just enforce that ports"},{"line_number":279,"context_line":"        # that have switchport configuration must have a"},{"line_number":280,"context_line":"        # local_link_connection?"},{"line_number":281,"context_line":"        LOG.warning("},{"line_number":282,"context_line":"            _(\"Node %(node)s requires at least one port with \""},{"line_number":283,"context_line":"              \"local_link_connection and valid mode/native_vlan \""}],"source_content_type":"text/x-python","patch_set":9,"id":"96eb7c42_d7364880","line":280,"updated":"2026-01-19 14:41:00.000000000","message":"This sounds like a good idea.","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"72dbce61b5652ecb5500c1d923537afad51d0022","unresolved":true,"context_lines":[{"line_number":277,"context_line":"        # cleaning or rescuing if we require ports to be present and"},{"line_number":278,"context_line":"        # configured.  Needs more thought.  Maybe just enforce that ports"},{"line_number":279,"context_line":"        # that have switchport configuration must have a"},{"line_number":280,"context_line":"        # local_link_connection?"},{"line_number":281,"context_line":"        LOG.warning("},{"line_number":282,"context_line":"            _(\"Node %(node)s requires at least one port with \""},{"line_number":283,"context_line":"              \"local_link_connection and valid mode/native_vlan \""}],"source_content_type":"text/x-python","patch_set":9,"id":"a5608049_15e12cbb","line":280,"in_reply_to":"96eb7c42_d7364880","updated":"2026-02-03 10:20:35.000000000","message":"This TODO is already technically implemented in the code as-is.","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"db419fee6ab6872074cafa89fc7934b17b56ce89","unresolved":true,"context_lines":[{"line_number":301,"context_line":"            if self.switchport_schema is not None:"},{"line_number":302,"context_line":"                jsonschema.validate(switchport_config,"},{"line_number":303,"context_line":"                                    self.switchport_schema)"},{"line_number":304,"context_line":"                LOG.debug(\"Port %s switchport configuration is valid\","},{"line_number":305,"context_line":"                          port.uuid)"},{"line_number":306,"context_line":"        except json_schema_exc.ValidationError as e:"},{"line_number":307,"context_line":"            raise exception.InvalidParameterValue("}],"source_content_type":"text/x-python","patch_set":9,"id":"df10bfcc_c6e09f69","line":304,"updated":"2026-01-19 14:41:00.000000000","message":"nit: this seems a bit excessive","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"2fa3d95546398907f71e7f712f006edf36bd34d0","unresolved":false,"context_lines":[{"line_number":301,"context_line":"            if self.switchport_schema is not None:"},{"line_number":302,"context_line":"                jsonschema.validate(switchport_config,"},{"line_number":303,"context_line":"                                    self.switchport_schema)"},{"line_number":304,"context_line":"                LOG.debug(\"Port %s switchport configuration is valid\","},{"line_number":305,"context_line":"                          port.uuid)"},{"line_number":306,"context_line":"        except json_schema_exc.ValidationError as e:"},{"line_number":307,"context_line":"            raise exception.InvalidParameterValue("}],"source_content_type":"text/x-python","patch_set":9,"id":"d946f10c_69273183","line":304,"in_reply_to":"df10bfcc_c6e09f69","updated":"2026-01-20 22:19:56.000000000","message":"Done","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"db419fee6ab6872074cafa89fc7934b17b56ce89","unresolved":true,"context_lines":[{"line_number":311,"context_line":"        # Validate that PXE-enabled ports use access mode"},{"line_number":312,"context_line":"        if port.pxe_enabled:"},{"line_number":313,"context_line":"            mode \u003d switchport_config.get(\u0027mode\u0027)"},{"line_number":314,"context_line":"            if mode in (\u0027trunk\u0027, \u0027hybrid\u0027):"},{"line_number":315,"context_line":"                raise exception.InvalidParameterValue("},{"line_number":316,"context_line":"                    _(\"Port %(port)s is PXE-enabled but has switchport mode \""},{"line_number":317,"context_line":"                      \"\u0027%(mode)s\u0027. PXE-enabled ports must use \u0027access\u0027 mode \""}],"source_content_type":"text/x-python","patch_set":9,"id":"75174972_0deb2b08","line":314,"updated":"2026-01-19 14:41:00.000000000","message":"nit for clarity: `if mode !\u003d \u0027access`:` seems to be what you\u0027re actually enforcing?","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"2fa3d95546398907f71e7f712f006edf36bd34d0","unresolved":false,"context_lines":[{"line_number":311,"context_line":"        # Validate that PXE-enabled ports use access mode"},{"line_number":312,"context_line":"        if port.pxe_enabled:"},{"line_number":313,"context_line":"            mode \u003d switchport_config.get(\u0027mode\u0027)"},{"line_number":314,"context_line":"            if mode in (\u0027trunk\u0027, \u0027hybrid\u0027):"},{"line_number":315,"context_line":"                raise exception.InvalidParameterValue("},{"line_number":316,"context_line":"                    _(\"Port %(port)s is PXE-enabled but has switchport mode \""},{"line_number":317,"context_line":"                      \"\u0027%(mode)s\u0027. PXE-enabled ports must use \u0027access\u0027 mode \""}],"source_content_type":"text/x-python","patch_set":9,"id":"c2045fd0_4365b2ba","line":314,"in_reply_to":"75174972_0deb2b08","updated":"2026-01-20 22:19:56.000000000","message":"Done","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"db419fee6ab6872074cafa89fc7934b17b56ce89","unresolved":true,"context_lines":[{"line_number":932,"context_line":""},{"line_number":933,"context_line":"        :param task: A TaskManager instance."},{"line_number":934,"context_line":"        \"\"\""},{"line_number":935,"context_line":"        LOG.info(\"Adding tenant networks to node %(node)s\","},{"line_number":936,"context_line":"                 {\u0027node\u0027: task.node.uuid})"},{"line_number":937,"context_line":""},{"line_number":938,"context_line":"        # Resolve the idle network configuration (if any)"}],"source_content_type":"text/x-python","patch_set":9,"id":"8264f7bc_cae227e8","line":935,"updated":"2026-01-19 14:41:00.000000000","message":"nit: s/info/debug/ (in-progress operation)","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"2fa3d95546398907f71e7f712f006edf36bd34d0","unresolved":false,"context_lines":[{"line_number":932,"context_line":""},{"line_number":933,"context_line":"        :param task: A TaskManager instance."},{"line_number":934,"context_line":"        \"\"\""},{"line_number":935,"context_line":"        LOG.info(\"Adding tenant networks to node %(node)s\","},{"line_number":936,"context_line":"                 {\u0027node\u0027: task.node.uuid})"},{"line_number":937,"context_line":""},{"line_number":938,"context_line":"        # Resolve the idle network configuration (if any)"}],"source_content_type":"text/x-python","patch_set":9,"id":"1bbd4841_88355757","line":935,"in_reply_to":"8264f7bc_cae227e8","updated":"2026-01-20 22:19:56.000000000","message":"Done","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"db419fee6ab6872074cafa89fc7934b17b56ce89","unresolved":true,"context_lines":[{"line_number":944,"context_line":"            link_info \u003d port.local_link_connection"},{"line_number":945,"context_line":""},{"line_number":946,"context_line":"            if not switchport or not link_info:"},{"line_number":947,"context_line":"                LOG.info("},{"line_number":948,"context_line":"                    \"Skipping port %(port)s: missing switchport or \""},{"line_number":949,"context_line":"                    \"local_link_connection info for tenant network setup.\","},{"line_number":950,"context_line":"                    {\u0027port\u0027: port.uuid}"}],"source_content_type":"text/x-python","patch_set":9,"id":"6b09f6b0_216bf8b5","line":947,"updated":"2026-01-19 14:41:00.000000000","message":"I think \"info\" is off here too: it\u0027s either insignificant in the normal case (then it\u0027s debug) or dangerous (then it\u0027s warning)","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"2fa3d95546398907f71e7f712f006edf36bd34d0","unresolved":false,"context_lines":[{"line_number":944,"context_line":"            link_info \u003d port.local_link_connection"},{"line_number":945,"context_line":""},{"line_number":946,"context_line":"            if not switchport or not link_info:"},{"line_number":947,"context_line":"                LOG.info("},{"line_number":948,"context_line":"                    \"Skipping port %(port)s: missing switchport or \""},{"line_number":949,"context_line":"                    \"local_link_connection info for tenant network setup.\","},{"line_number":950,"context_line":"                    {\u0027port\u0027: port.uuid}"}],"source_content_type":"text/x-python","patch_set":9,"id":"b276af05_25f1b08d","line":947,"in_reply_to":"6b09f6b0_216bf8b5","updated":"2026-01-20 22:19:56.000000000","message":"Done","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"db419fee6ab6872074cafa89fc7934b17b56ce89","unresolved":true,"context_lines":[{"line_number":956,"context_line":"            allowed_vlans \u003d switchport.get(\u0027allowed_vlans\u0027)"},{"line_number":957,"context_line":""},{"line_number":958,"context_line":"            if not mode or native_vlan is None:"},{"line_number":959,"context_line":"                LOG.info("},{"line_number":960,"context_line":"                    \"Skipping port %(port)s: missing mode or native_vlan for \""},{"line_number":961,"context_line":"                    \"tenant network setup.\","},{"line_number":962,"context_line":"                    {\u0027port\u0027: port.uuid}"}],"source_content_type":"text/x-python","patch_set":9,"id":"c6126539_5f3c8f3c","line":959,"updated":"2026-01-19 14:41:00.000000000","message":"same","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"2fa3d95546398907f71e7f712f006edf36bd34d0","unresolved":false,"context_lines":[{"line_number":956,"context_line":"            allowed_vlans \u003d switchport.get(\u0027allowed_vlans\u0027)"},{"line_number":957,"context_line":""},{"line_number":958,"context_line":"            if not mode or native_vlan is None:"},{"line_number":959,"context_line":"                LOG.info("},{"line_number":960,"context_line":"                    \"Skipping port %(port)s: missing mode or native_vlan for \""},{"line_number":961,"context_line":"                    \"tenant network setup.\","},{"line_number":962,"context_line":"                    {\u0027port\u0027: port.uuid}"}],"source_content_type":"text/x-python","patch_set":9,"id":"ec0bb9ce_9492b8e9","line":959,"in_reply_to":"c6126539_5f3c8f3c","updated":"2026-01-20 22:19:56.000000000","message":"Done","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"db419fee6ab6872074cafa89fc7934b17b56ce89","unresolved":true,"context_lines":[{"line_number":980,"context_line":"                    \"Failed to update port %(port)s for tenant network: \""},{"line_number":981,"context_line":"                    \"%(err)s\","},{"line_number":982,"context_line":"                    {\u0027port\u0027: port.uuid, \u0027err\u0027: exc}"},{"line_number":983,"context_line":"                )"},{"line_number":984,"context_line":""},{"line_number":985,"context_line":"    def _remove_tenant_networks(self, task):"},{"line_number":986,"context_line":"        \"\"\"Remove tenant networks from a node."}],"source_content_type":"text/x-python","patch_set":9,"id":"98c677fd_a7b3125a","line":983,"updated":"2026-01-19 14:41:00.000000000","message":"Why not raise here and in _remove_tenant_network? We don\u0027t want this to be treated as success","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"2fa3d95546398907f71e7f712f006edf36bd34d0","unresolved":false,"context_lines":[{"line_number":980,"context_line":"                    \"Failed to update port %(port)s for tenant network: \""},{"line_number":981,"context_line":"                    \"%(err)s\","},{"line_number":982,"context_line":"                    {\u0027port\u0027: port.uuid, \u0027err\u0027: exc}"},{"line_number":983,"context_line":"                )"},{"line_number":984,"context_line":""},{"line_number":985,"context_line":"    def _remove_tenant_networks(self, task):"},{"line_number":986,"context_line":"        \"\"\"Remove tenant networks from a node."}],"source_content_type":"text/x-python","patch_set":9,"id":"11db6bd5_e22ae11f","line":983,"in_reply_to":"98c677fd_a7b3125a","updated":"2026-01-20 22:19:56.000000000","message":"Done","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"db419fee6ab6872074cafa89fc7934b17b56ce89","unresolved":true,"context_lines":[{"line_number":1005,"context_line":"            link_info \u003d port.local_link_connection"},{"line_number":1006,"context_line":""},{"line_number":1007,"context_line":"            if not switchport or not link_info:"},{"line_number":1008,"context_line":"                LOG.info("},{"line_number":1009,"context_line":"                    \"Skipping port %(port)s: missing switchport or \""},{"line_number":1010,"context_line":"                    \"local_link_connection info for tenant network removal.\","},{"line_number":1011,"context_line":"                    {\u0027port\u0027: port.uuid}"}],"source_content_type":"text/x-python","patch_set":9,"id":"7733507a_cd488f45","line":1008,"updated":"2026-01-19 14:41:00.000000000","message":"same re logging","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"2fa3d95546398907f71e7f712f006edf36bd34d0","unresolved":false,"context_lines":[{"line_number":1005,"context_line":"            link_info \u003d port.local_link_connection"},{"line_number":1006,"context_line":""},{"line_number":1007,"context_line":"            if not switchport or not link_info:"},{"line_number":1008,"context_line":"                LOG.info("},{"line_number":1009,"context_line":"                    \"Skipping port %(port)s: missing switchport or \""},{"line_number":1010,"context_line":"                    \"local_link_connection info for tenant network removal.\","},{"line_number":1011,"context_line":"                    {\u0027port\u0027: port.uuid}"}],"source_content_type":"text/x-python","patch_set":9,"id":"f6c8431a_7ef4d118","line":1008,"in_reply_to":"7733507a_cd488f45","updated":"2026-01-20 22:19:56.000000000","message":"Done","commit_id":"4e4540557f2710bb7bf88e9aeb7247269ca6259a"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":49,"context_line":"_LAG_SCHEMA \u003d None"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"# States related to inspection."},{"line_number":52,"context_line":"_INSPECTION_STATES \u003d ["},{"line_number":53,"context_line":"    states.INSPECTING,"},{"line_number":54,"context_line":"    states.INSPECTWAIT,"},{"line_number":55,"context_line":"    states.INSPECTFAIL"}],"source_content_type":"text/x-python","patch_set":10,"id":"657743d5_d26cfea0","line":52,"updated":"2026-01-26 19:24:38.000000000","message":"Ideally, we\u0027d put INSPECTION_STATES into ironic/common/states.py","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":49,"context_line":"_LAG_SCHEMA \u003d None"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"# States related to inspection."},{"line_number":52,"context_line":"_INSPECTION_STATES \u003d ["},{"line_number":53,"context_line":"    states.INSPECTING,"},{"line_number":54,"context_line":"    states.INSPECTWAIT,"},{"line_number":55,"context_line":"    states.INSPECTFAIL"}],"source_content_type":"text/x-python","patch_set":10,"id":"99375ff8_90c8a9f5","line":52,"in_reply_to":"657743d5_d26cfea0","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":63,"context_line":"    global _SWITCHPORT_SCHEMA, _LAG_SCHEMA"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    # Load switchport schema"},{"line_number":66,"context_line":"    schema_file \u003d os.path.join("},{"line_number":67,"context_line":"        os.path.dirname(__file__),"},{"line_number":68,"context_line":"        \u0027schemas\u0027, \u0027ironic-networking-switchport.schema.json\u0027)"},{"line_number":69,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":10,"id":"80fd7198_46bf57d7","line":66,"updated":"2026-01-26 19:24:38.000000000","message":"It weirds me out that we\u0027re loading these from file here, but in literally every other use case in Ironic we\u0027re inlining the schemas; e.g. https://opendev.org/openstack/ironic/src/commit/c92870f01e1b304b40bed30641f25f1e141f9cb3/ironic/api/controllers/v1/utils.py#L1026 \n\nWe should strive for consistency, and this is highly inconsistent. If we prefer files; lets use files everywhere -- I don\u0027t like that this is different for code that does the same thing though.","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"8f498a8a50c2b42797928e6a45762971321450cf","unresolved":true,"context_lines":[{"line_number":63,"context_line":"    global _SWITCHPORT_SCHEMA, _LAG_SCHEMA"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    # Load switchport schema"},{"line_number":66,"context_line":"    schema_file \u003d os.path.join("},{"line_number":67,"context_line":"        os.path.dirname(__file__),"},{"line_number":68,"context_line":"        \u0027schemas\u0027, \u0027ironic-networking-switchport.schema.json\u0027)"},{"line_number":69,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":10,"id":"b211cf9c_eaabb4c8","line":66,"in_reply_to":"46e0bb40_bbe00a06","updated":"2026-01-27 13:28:11.000000000","message":"This definitely will work for deb and rpm, it will only fail for importing Ironic directly from a ZIP file, which is already very broken in PXE, iPXE and RAID.","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"3e3bda5d23c5c272c188dda910edbfb086495c5b","unresolved":true,"context_lines":[{"line_number":63,"context_line":"    global _SWITCHPORT_SCHEMA, _LAG_SCHEMA"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    # Load switchport schema"},{"line_number":66,"context_line":"    schema_file \u003d os.path.join("},{"line_number":67,"context_line":"        os.path.dirname(__file__),"},{"line_number":68,"context_line":"        \u0027schemas\u0027, \u0027ironic-networking-switchport.schema.json\u0027)"},{"line_number":69,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":10,"id":"2dff2f01_553a61cf","line":66,"in_reply_to":"4fba18ae_1eb6af9e","updated":"2026-01-27 19:59:15.000000000","message":"I still have a preference for the constants method, but my main concern is that things work.","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":63,"context_line":"    global _SWITCHPORT_SCHEMA, _LAG_SCHEMA"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    # Load switchport schema"},{"line_number":66,"context_line":"    schema_file \u003d os.path.join("},{"line_number":67,"context_line":"        os.path.dirname(__file__),"},{"line_number":68,"context_line":"        \u0027schemas\u0027, \u0027ironic-networking-switchport.schema.json\u0027)"},{"line_number":69,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":10,"id":"f219dd8a_130e136a","line":66,"in_reply_to":"4fba18ae_1eb6af9e","updated":"2026-01-28 14:43:59.000000000","message":"moved to constants in ironic_networking_schemas.py","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"d87e7b77125b318d11fa8a4d95f0168a6aa9f449","unresolved":true,"context_lines":[{"line_number":63,"context_line":"    global _SWITCHPORT_SCHEMA, _LAG_SCHEMA"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    # Load switchport schema"},{"line_number":66,"context_line":"    schema_file \u003d os.path.join("},{"line_number":67,"context_line":"        os.path.dirname(__file__),"},{"line_number":68,"context_line":"        \u0027schemas\u0027, \u0027ironic-networking-switchport.schema.json\u0027)"},{"line_number":69,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":10,"id":"46e0bb40_bbe00a06","line":66,"in_reply_to":"69684d7c_c8e7ca7b","updated":"2026-01-27 12:53:32.000000000","message":"We do the same for RAID, and it surely works https://opendev.org/openstack/ironic/src/commit/c92870f01e1b304b40bed30641f25f1e141f9cb3/ironic/drivers/base.py#L38-L39","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":5890,"name":"Doug Goldstein","email":"cardoe@cardoe.com","username":"cardoe"},"change_message_id":"69420ce826a7d55f9a862568c2585ade05a7c09f","unresolved":true,"context_lines":[{"line_number":63,"context_line":"    global _SWITCHPORT_SCHEMA, _LAG_SCHEMA"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    # Load switchport schema"},{"line_number":66,"context_line":"    schema_file \u003d os.path.join("},{"line_number":67,"context_line":"        os.path.dirname(__file__),"},{"line_number":68,"context_line":"        \u0027schemas\u0027, \u0027ironic-networking-switchport.schema.json\u0027)"},{"line_number":69,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":10,"id":"ce4a92c0_6fad9806","line":66,"in_reply_to":"80fd7198_46bf57d7","updated":"2026-01-26 21:25:20.000000000","message":"So I don\u0027t hate it. But the implementation is definitely wrong for installed packages. This will work for a package installed editable (like the tests do) and then fail for a package build for deb or rpm. https://docs.python.org/3/library/importlib.resources.html","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"d61780c597fa90aa14e40fb19d5e7051f3af86a2","unresolved":true,"context_lines":[{"line_number":63,"context_line":"    global _SWITCHPORT_SCHEMA, _LAG_SCHEMA"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    # Load switchport schema"},{"line_number":66,"context_line":"    schema_file \u003d os.path.join("},{"line_number":67,"context_line":"        os.path.dirname(__file__),"},{"line_number":68,"context_line":"        \u0027schemas\u0027, \u0027ironic-networking-switchport.schema.json\u0027)"},{"line_number":69,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":10,"id":"4fba18ae_1eb6af9e","line":66,"in_reply_to":"b211cf9c_eaabb4c8","updated":"2026-01-27 13:31:03.000000000","message":"Seems like making a simple change to how the file is located would solve the zip case as well.  Something like:\n\n```\nfrom importlib.resources import files                                                                                                                                                                                                                                                                           \n                                                                                                                                                                                                                                                                                                                  \n  schema_data \u003d files(__package__).joinpath(                                                                                                                                                                                                                                                                      \n      \u0027schemas\u0027, \u0027ironic-networking-switchport.schema.json\u0027).read_text()                                                                                                                                                                                                                                          \n  _SWITCHPORT_SCHEMA \u003d json.loads(schema_data) \n```","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"724fb2630b624a114b0de09c36212e0736415b03","unresolved":true,"context_lines":[{"line_number":63,"context_line":"    global _SWITCHPORT_SCHEMA, _LAG_SCHEMA"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    # Load switchport schema"},{"line_number":66,"context_line":"    schema_file \u003d os.path.join("},{"line_number":67,"context_line":"        os.path.dirname(__file__),"},{"line_number":68,"context_line":"        \u0027schemas\u0027, \u0027ironic-networking-switchport.schema.json\u0027)"},{"line_number":69,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":10,"id":"69684d7c_c8e7ca7b","line":66,"in_reply_to":"ce4a92c0_6fad9806","updated":"2026-01-26 22:02:03.000000000","message":"Please just move them back to constants so everything remains consistent.","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":208,"context_line":"                native_vlan \u003d int(vlan_part.split(\u0027\u003d\u0027, 1)[1])"},{"line_number":209,"context_line":"            else:"},{"line_number":210,"context_line":"                native_vlan \u003d None"},{"line_number":211,"context_line":"        except Exception as e:"},{"line_number":212,"context_line":"            raise exception.InvalidParameterValue("},{"line_number":213,"context_line":"                _(\"Invalid %(network_type)s network value \u0027%(value)s\u0027. \""},{"line_number":214,"context_line":"                  \"Expected: {access|trunk|hybrid}/native_vlan\u003dVLAN_ID. \""}],"source_content_type":"text/x-python","patch_set":10,"id":"e4c79a87_36db3e11","line":211,"updated":"2026-01-26 19:24:38.000000000","message":"except Exception is not OK -- we need specificity and this re-raise hides the errors","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":208,"context_line":"                native_vlan \u003d int(vlan_part.split(\u0027\u003d\u0027, 1)[1])"},{"line_number":209,"context_line":"            else:"},{"line_number":210,"context_line":"                native_vlan \u003d None"},{"line_number":211,"context_line":"        except Exception as e:"},{"line_number":212,"context_line":"            raise exception.InvalidParameterValue("},{"line_number":213,"context_line":"                _(\"Invalid %(network_type)s network value \u0027%(value)s\u0027. \""},{"line_number":214,"context_line":"                  \"Expected: {access|trunk|hybrid}/native_vlan\u003dVLAN_ID. \""}],"source_content_type":"text/x-python","patch_set":10,"id":"7e8a24bb_30bd1086","line":211,"in_reply_to":"e4c79a87_36db3e11","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":223,"context_line":"            \"from value\u003d\u0027%(value)s\u0027\","},{"line_number":224,"context_line":"            {\u0027node\u0027: task.node.uuid, \u0027network_type\u0027: network_type,"},{"line_number":225,"context_line":"             \u0027mode\u0027: mode, \u0027native_vlan\u0027: native_vlan,"},{"line_number":226,"context_line":"             \u0027allowed_vlans\u0027: allowed_vlans, \u0027value\u0027: network_value})"},{"line_number":227,"context_line":""},{"line_number":228,"context_line":"        return mode, native_vlan, allowed_vlans"},{"line_number":229,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"cfbc2894_46ab5c74","line":226,"updated":"2026-01-26 19:24:38.000000000","message":"allowed_vlans is always None in this codepath; remove from logging?","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":223,"context_line":"            \"from value\u003d\u0027%(value)s\u0027\","},{"line_number":224,"context_line":"            {\u0027node\u0027: task.node.uuid, \u0027network_type\u0027: network_type,"},{"line_number":225,"context_line":"             \u0027mode\u0027: mode, \u0027native_vlan\u0027: native_vlan,"},{"line_number":226,"context_line":"             \u0027allowed_vlans\u0027: allowed_vlans, \u0027value\u0027: network_value})"},{"line_number":227,"context_line":""},{"line_number":228,"context_line":"        return mode, native_vlan, allowed_vlans"},{"line_number":229,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"e75552dd_3d1d8601","line":226,"in_reply_to":"cfbc2894_46ab5c74","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":239,"context_line":"        :param network_type: The type of network to validate (e.g.,"},{"line_number":240,"context_line":"                             \u0027cleaning\u0027, \u0027rescuing\u0027, \u0027inspection\u0027,"},{"line_number":241,"context_line":"                             \u0027servicing\u0027)."},{"line_number":242,"context_line":"        :raises: MissingParameterValue if no valid ports are found for"},{"line_number":243,"context_line":"                 the network."},{"line_number":244,"context_line":"        \"\"\""},{"line_number":245,"context_line":"        for port in task.ports:"}],"source_content_type":"text/x-python","patch_set":10,"id":"53335783_f48d6778","line":242,"updated":"2026-01-26 19:24:38.000000000","message":"It doesn\u0027t -- it\u0027s an InvalidParameterValue -- at least until you address the comments about exception handling.","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"2e9e6d935fb2f5b0465df3b7e7df681c5feada5b","unresolved":true,"context_lines":[{"line_number":239,"context_line":"        :param network_type: The type of network to validate (e.g.,"},{"line_number":240,"context_line":"                             \u0027cleaning\u0027, \u0027rescuing\u0027, \u0027inspection\u0027,"},{"line_number":241,"context_line":"                             \u0027servicing\u0027)."},{"line_number":242,"context_line":"        :raises: MissingParameterValue if no valid ports are found for"},{"line_number":243,"context_line":"                 the network."},{"line_number":244,"context_line":"        \"\"\""},{"line_number":245,"context_line":"        for port in task.ports:"}],"source_content_type":"text/x-python","patch_set":10,"id":"8775c056_08d0b2c0","line":242,"updated":"2026-01-26 18:29:04.000000000","message":"Likely meaning InvalidParameterValue","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":239,"context_line":"        :param network_type: The type of network to validate (e.g.,"},{"line_number":240,"context_line":"                             \u0027cleaning\u0027, \u0027rescuing\u0027, \u0027inspection\u0027,"},{"line_number":241,"context_line":"                             \u0027servicing\u0027)."},{"line_number":242,"context_line":"        :raises: MissingParameterValue if no valid ports are found for"},{"line_number":243,"context_line":"                 the network."},{"line_number":244,"context_line":"        \"\"\""},{"line_number":245,"context_line":"        for port in task.ports:"}],"source_content_type":"text/x-python","patch_set":10,"id":"bbd45688_4a28d1a8","line":242,"in_reply_to":"53335783_f48d6778","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":239,"context_line":"        :param network_type: The type of network to validate (e.g.,"},{"line_number":240,"context_line":"                             \u0027cleaning\u0027, \u0027rescuing\u0027, \u0027inspection\u0027,"},{"line_number":241,"context_line":"                             \u0027servicing\u0027)."},{"line_number":242,"context_line":"        :raises: MissingParameterValue if no valid ports are found for"},{"line_number":243,"context_line":"                 the network."},{"line_number":244,"context_line":"        \"\"\""},{"line_number":245,"context_line":"        for port in task.ports:"}],"source_content_type":"text/x-python","patch_set":10,"id":"d0f35ff6_95c9d8ce","line":242,"in_reply_to":"8775c056_08d0b2c0","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":286,"context_line":"        :raises: InvalidParameterValue if switchport configuration is invalid."},{"line_number":287,"context_line":"        \"\"\""},{"line_number":288,"context_line":"        if not port.extra:"},{"line_number":289,"context_line":"            return"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        switchport_config \u003d port.extra.get(\u0027switchport\u0027)"},{"line_number":292,"context_line":"        if not switchport_config:"}],"source_content_type":"text/x-python","patch_set":10,"id":"d63e3de7_430ff0db","line":289,"updated":"2026-01-26 19:24:38.000000000","message":"We may want to specifically point out that the use of extra to store switchport info is the part of the API most likely to change in docs.","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":286,"context_line":"        :raises: InvalidParameterValue if switchport configuration is invalid."},{"line_number":287,"context_line":"        \"\"\""},{"line_number":288,"context_line":"        if not port.extra:"},{"line_number":289,"context_line":"            return"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        switchport_config \u003d port.extra.get(\u0027switchport\u0027)"},{"line_number":292,"context_line":"        if not switchport_config:"}],"source_content_type":"text/x-python","patch_set":10,"id":"9ccfd143_94007987","line":289,"in_reply_to":"d63e3de7_430ff0db","updated":"2026-01-28 14:43:59.000000000","message":"i\u0027ll add a note to the user guide docs.","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":340,"context_line":"        if not port_id:"},{"line_number":341,"context_line":"            raise exception.InvalidParameterValue("},{"line_number":342,"context_line":"                _(\"Port %(port)s local_link_connection missing required \""},{"line_number":343,"context_line":"                  \"\u0027port_id\u0027 field\") % {\u0027port\u0027: port.uuid})"},{"line_number":344,"context_line":""},{"line_number":345,"context_line":"    def _validate_portgroup_lag_config(self, portgroup):"},{"line_number":346,"context_line":"        \"\"\"Validate LAG configuration in portgroup\u0027s extra field."}],"source_content_type":"text/x-python","patch_set":10,"id":"d2d1e13d_7fab0910","line":343,"updated":"2026-01-26 19:24:38.000000000","message":"If we have no switch_id AND no port_id, we need to send that feedback to users. Maybe a collect_errors style pattern?","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":340,"context_line":"        if not port_id:"},{"line_number":341,"context_line":"            raise exception.InvalidParameterValue("},{"line_number":342,"context_line":"                _(\"Port %(port)s local_link_connection missing required \""},{"line_number":343,"context_line":"                  \"\u0027port_id\u0027 field\") % {\u0027port\u0027: port.uuid})"},{"line_number":344,"context_line":""},{"line_number":345,"context_line":"    def _validate_portgroup_lag_config(self, portgroup):"},{"line_number":346,"context_line":"        \"\"\"Validate LAG configuration in portgroup\u0027s extra field."}],"source_content_type":"text/x-python","patch_set":10,"id":"46040621_7c29026f","line":343,"in_reply_to":"d2d1e13d_7fab0910","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":413,"context_line":"                  \"switchport configuration but lack proper \""},{"line_number":414,"context_line":"                  \"local_link_connection with switch_id and port_id fields.\") %"},{"line_number":415,"context_line":"                {\u0027portgroup\u0027: portgroup.uuid,"},{"line_number":416,"context_line":"                 \u0027ports\u0027: \u0027, \u0027.join(ports_without_local_link)})"},{"line_number":417,"context_line":""},{"line_number":418,"context_line":"    @staticmethod"},{"line_number":419,"context_line":"    def _get_portgroup_switch_ids(task, portgroup):"}],"source_content_type":"text/x-python","patch_set":10,"id":"dd8b8f38_e114a24e","line":416,"updated":"2026-01-26 19:24:38.000000000","message":"Operators with ports missing switchport AND local_link should get back a single error when they do it.","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":413,"context_line":"                  \"switchport configuration but lack proper \""},{"line_number":414,"context_line":"                  \"local_link_connection with switch_id and port_id fields.\") %"},{"line_number":415,"context_line":"                {\u0027portgroup\u0027: portgroup.uuid,"},{"line_number":416,"context_line":"                 \u0027ports\u0027: \u0027, \u0027.join(ports_without_local_link)})"},{"line_number":417,"context_line":""},{"line_number":418,"context_line":"    @staticmethod"},{"line_number":419,"context_line":"    def _get_portgroup_switch_ids(task, portgroup):"}],"source_content_type":"text/x-python","patch_set":10,"id":"ae29471b_18ce93e8","line":416,"in_reply_to":"dd8b8f38_e114a24e","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":459,"context_line":"            return portgroup.name"},{"line_number":460,"context_line":"        else:"},{"line_number":461,"context_line":"            # Fallback to using UUID prefix if no name is set"},{"line_number":462,"context_line":"            return f\"lag-{portgroup.uuid[:8]}\""},{"line_number":463,"context_line":""},{"line_number":464,"context_line":"    @staticmethod"},{"line_number":465,"context_line":"    def _get_port_switch_info(port):"}],"source_content_type":"text/x-python","patch_set":10,"id":"d61f5d94_ec445325","line":462,"updated":"2026-01-26 19:24:38.000000000","message":"Let\u0027s watch out for collisions -- this should be guaranteed-unique per switch.\n\nhash(port_ids) would be an idea, but not-reversible\n\nLAG is outta scope for this change, but lets add a TODO in this change or in a followup.","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":459,"context_line":"            return portgroup.name"},{"line_number":460,"context_line":"        else:"},{"line_number":461,"context_line":"            # Fallback to using UUID prefix if no name is set"},{"line_number":462,"context_line":"            return f\"lag-{portgroup.uuid[:8]}\""},{"line_number":463,"context_line":""},{"line_number":464,"context_line":"    @staticmethod"},{"line_number":465,"context_line":"    def _get_port_switch_info(port):"}],"source_content_type":"text/x-python","patch_set":10,"id":"1d27c308_d5ffb3f3","line":462,"in_reply_to":"d61f5d94_ec445325","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":526,"context_line":"            # leaving any of the other states mentioned above means that the"},{"line_number":527,"context_line":"            # previous network was removed.  In this case we should fallback"},{"line_number":528,"context_line":"            # to the idle network."},{"line_number":529,"context_line":"            return network.IDLE_NETWORK"},{"line_number":530,"context_line":""},{"line_number":531,"context_line":"    def _resolve_network_configuration(self, task, port_obj, network_type):"},{"line_number":532,"context_line":"        \"\"\"Resolve network configuration for a port based on network type."}],"source_content_type":"text/x-python","patch_set":10,"id":"7a9721ef_7f2e8c1d","line":529,"updated":"2026-01-26 19:24:38.000000000","message":"This is encoding *Ironic* business logic as much as it is ironic-networking business logic. I think in a perfect world, we\u0027d have \"network type\" to state mappings in a common place, like ironic/common/states.py or ironic/common/network.py.","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":526,"context_line":"            # leaving any of the other states mentioned above means that the"},{"line_number":527,"context_line":"            # previous network was removed.  In this case we should fallback"},{"line_number":528,"context_line":"            # to the idle network."},{"line_number":529,"context_line":"            return network.IDLE_NETWORK"},{"line_number":530,"context_line":""},{"line_number":531,"context_line":"    def _resolve_network_configuration(self, task, port_obj, network_type):"},{"line_number":532,"context_line":"        \"\"\"Resolve network configuration for a port based on network type."}],"source_content_type":"text/x-python","patch_set":10,"id":"5e4314cb_33cd6218","line":529,"in_reply_to":"7a9721ef_7f2e8c1d","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":534,"context_line":"        :param task: A TaskManager instance."},{"line_number":535,"context_line":"        :param port_obj: A Port object."},{"line_number":536,"context_line":"        :param network_type: The type of network to resolve configuration for."},{"line_number":537,"context_line":"        :returns: Tuple of (mode, native_vlan, allowed_vlans)."},{"line_number":538,"context_line":"        \"\"\""},{"line_number":539,"context_line":"        # Try network-specific configuration first"},{"line_number":540,"context_line":"        mode, native_vlan, allowed_vlans \u003d self._get_network_mode_and_vlan("}],"source_content_type":"text/x-python","patch_set":10,"id":"8a86a754_93051341","line":537,"updated":"2026-01-26 19:24:38.000000000","message":"_get_network_mode_and_vlan can raise; please indicate so","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":534,"context_line":"        :param task: A TaskManager instance."},{"line_number":535,"context_line":"        :param port_obj: A Port object."},{"line_number":536,"context_line":"        :param network_type: The type of network to resolve configuration for."},{"line_number":537,"context_line":"        :returns: Tuple of (mode, native_vlan, allowed_vlans)."},{"line_number":538,"context_line":"        \"\"\""},{"line_number":539,"context_line":"        # Try network-specific configuration first"},{"line_number":540,"context_line":"        mode, native_vlan, allowed_vlans \u003d self._get_network_mode_and_vlan("}],"source_content_type":"text/x-python","patch_set":10,"id":"11a5bd52_9d4bd8bf","line":537,"in_reply_to":"8a86a754_93051341","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":566,"context_line":"        return mode, native_vlan, allowed_vlans"},{"line_number":567,"context_line":""},{"line_number":568,"context_line":"    def _get_original_port_config(self, task, port_obj):"},{"line_number":569,"context_line":"        \"\"\"Get original port configuration before changes.\"\"\""},{"line_number":570,"context_line":"        original_port \u003d None"},{"line_number":571,"context_line":"        try:"},{"line_number":572,"context_line":"            for port in task.ports:"}],"source_content_type":"text/x-python","patch_set":10,"id":"32f4752d_eef45ef9","line":569,"updated":"2026-01-26 19:24:38.000000000","message":"for port changes? Just a little more beef in the docstring please","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":566,"context_line":"        return mode, native_vlan, allowed_vlans"},{"line_number":567,"context_line":""},{"line_number":568,"context_line":"    def _get_original_port_config(self, task, port_obj):"},{"line_number":569,"context_line":"        \"\"\"Get original port configuration before changes.\"\"\""},{"line_number":570,"context_line":"        original_port \u003d None"},{"line_number":571,"context_line":"        try:"},{"line_number":572,"context_line":"            for port in task.ports:"}],"source_content_type":"text/x-python","patch_set":10,"id":"7e6bbc29_ab397298","line":569,"in_reply_to":"32f4752d_eef45ef9","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":573,"context_line":"                if port.uuid \u003d\u003d port_obj.uuid:"},{"line_number":574,"context_line":"                    original_port \u003d port"},{"line_number":575,"context_line":"                    break"},{"line_number":576,"context_line":"        except Exception:"},{"line_number":577,"context_line":"            # If we can\u0027t find the original port, treat as new configuration"},{"line_number":578,"context_line":"            original_port \u003d None"},{"line_number":579,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"a508cf88_04f00ab5","line":576,"updated":"2026-01-26 19:24:38.000000000","message":"no bare except Exception, please","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":573,"context_line":"                if port.uuid \u003d\u003d port_obj.uuid:"},{"line_number":574,"context_line":"                    original_port \u003d port"},{"line_number":575,"context_line":"                    break"},{"line_number":576,"context_line":"        except Exception:"},{"line_number":577,"context_line":"            # If we can\u0027t find the original port, treat as new configuration"},{"line_number":578,"context_line":"            original_port \u003d None"},{"line_number":579,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"2c3fdf0d_03bd5206","line":576,"in_reply_to":"a508cf88_04f00ab5","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":588,"context_line":""},{"line_number":589,"context_line":"    def _determine_port_changes(self, original_switchport, current_switchport,"},{"line_number":590,"context_line":"                                original_local_link, current_local_link):"},{"line_number":591,"context_line":"        \"\"\"Determine what changes occurred to the port.\"\"\""},{"line_number":592,"context_line":"        switchport_removed \u003d original_switchport and not current_switchport"},{"line_number":593,"context_line":"        local_link_removed \u003d original_local_link and not current_local_link"},{"line_number":594,"context_line":"        local_link_changed \u003d (original_local_link !\u003d current_local_link"}],"source_content_type":"text/x-python","patch_set":10,"id":"1d9ab98a_7f24c701","line":591,"updated":"2026-01-26 19:24:38.000000000","message":"more verbose docstring please","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":588,"context_line":""},{"line_number":589,"context_line":"    def _determine_port_changes(self, original_switchport, current_switchport,"},{"line_number":590,"context_line":"                                original_local_link, current_local_link):"},{"line_number":591,"context_line":"        \"\"\"Determine what changes occurred to the port.\"\"\""},{"line_number":592,"context_line":"        switchport_removed \u003d original_switchport and not current_switchport"},{"line_number":593,"context_line":"        local_link_removed \u003d original_local_link and not current_local_link"},{"line_number":594,"context_line":"        local_link_changed \u003d (original_local_link !\u003d current_local_link"}],"source_content_type":"text/x-python","patch_set":10,"id":"49a5b248_9efd48a2","line":591,"in_reply_to":"1d9ab98a_7f24c701","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":633,"context_line":"                            original_native_vlan,"},{"line_number":634,"context_line":"                            allowed_vlans\u003doriginal_allowed_vlans,"},{"line_number":635,"context_line":"                            default_vlan\u003didle_native_vlan)"},{"line_number":636,"context_line":"                        LOG.info("},{"line_number":637,"context_line":"                            \"Successfully reset port %(port_name)s on \""},{"line_number":638,"context_line":"                            \"switch %(switch_id)s via networking service: \""},{"line_number":639,"context_line":"                            \"%(result)s\","}],"source_content_type":"text/x-python","patch_set":10,"id":"ad7bae63_08831cfb","line":636,"updated":"2026-01-26 19:24:38.000000000","message":"probably should be debug; especially since we warn in the else","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":633,"context_line":"                            original_native_vlan,"},{"line_number":634,"context_line":"                            allowed_vlans\u003doriginal_allowed_vlans,"},{"line_number":635,"context_line":"                            default_vlan\u003didle_native_vlan)"},{"line_number":636,"context_line":"                        LOG.info("},{"line_number":637,"context_line":"                            \"Successfully reset port %(port_name)s on \""},{"line_number":638,"context_line":"                            \"switch %(switch_id)s via networking service: \""},{"line_number":639,"context_line":"                            \"%(result)s\","}],"source_content_type":"text/x-python","patch_set":10,"id":"e4eccbca_a59023bd","line":636,"in_reply_to":"ad7bae63_08831cfb","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":650,"context_line":"                        \"Cannot reset port %(port)s: missing mode or \""},{"line_number":651,"context_line":"                        \"native_vlan for %(active_network_type)s network\","},{"line_number":652,"context_line":"                        {\u0027port\u0027: port_obj.uuid})"},{"line_number":653,"context_line":"            except Exception as e:"},{"line_number":654,"context_line":"                LOG.error("},{"line_number":655,"context_line":"                    \"Failed to reset port %(port)s via networking \""},{"line_number":656,"context_line":"                    \"service: %(error)s\","}],"source_content_type":"text/x-python","patch_set":10,"id":"1bbb7795_3fdaf735","line":653,"updated":"2026-01-26 19:24:38.000000000","message":"please no bare except Exception (if you must; please re-raise it but I think we can get the whole list here)","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":650,"context_line":"                        \"Cannot reset port %(port)s: missing mode or \""},{"line_number":651,"context_line":"                        \"native_vlan for %(active_network_type)s network\","},{"line_number":652,"context_line":"                        {\u0027port\u0027: port_obj.uuid})"},{"line_number":653,"context_line":"            except Exception as e:"},{"line_number":654,"context_line":"                LOG.error("},{"line_number":655,"context_line":"                    \"Failed to reset port %(port)s via networking \""},{"line_number":656,"context_line":"                    \"service: %(error)s\","}],"source_content_type":"text/x-python","patch_set":10,"id":"2ecd85e8_5c4d32fa","line":653,"in_reply_to":"1bbb7795_3fdaf735","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":692,"context_line":"                            {\u0027port_name\u0027: port_name,"},{"line_number":693,"context_line":"                             \u0027switch_id\u0027: switch_id,"},{"line_number":694,"context_line":"                             \u0027result\u0027: result})"},{"line_number":695,"context_line":"            except Exception as e:"},{"line_number":696,"context_line":"                LOG.error("},{"line_number":697,"context_line":"                    \"Failed to reset old port %(port)s via \""},{"line_number":698,"context_line":"                    \"networking service: %(error)s\","}],"source_content_type":"text/x-python","patch_set":10,"id":"27578d90_3b83f446","line":695,"updated":"2026-01-26 19:24:38.000000000","message":"similar to above method: no bare exception catching; if you must ensure it\u0027s re-raised","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":692,"context_line":"                            {\u0027port_name\u0027: port_name,"},{"line_number":693,"context_line":"                             \u0027switch_id\u0027: switch_id,"},{"line_number":694,"context_line":"                             \u0027result\u0027: result})"},{"line_number":695,"context_line":"            except Exception as e:"},{"line_number":696,"context_line":"                LOG.error("},{"line_number":697,"context_line":"                    \"Failed to reset old port %(port)s via \""},{"line_number":698,"context_line":"                    \"networking service: %(error)s\","}],"source_content_type":"text/x-python","patch_set":10,"id":"e5816da5_71fca22a","line":695,"in_reply_to":"27578d90_3b83f446","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":856,"context_line":"        :param task: A TaskManager instance."},{"line_number":857,"context_line":"        :param portgroup_obj: A changed Portgroup object."},{"line_number":858,"context_line":"        \"\"\""},{"line_number":859,"context_line":"        LOG.info("},{"line_number":860,"context_line":"            \"Portgroup %(portgroup)s (%(name)s) configuration changed - \""},{"line_number":861,"context_line":"            \"portgroup changes not currently supported by \""},{"line_number":862,"context_line":"            \"ironic-networking interface\","}],"source_content_type":"text/x-python","patch_set":10,"id":"68021af0_c80ff645","line":859,"updated":"2026-01-26 19:24:38.000000000","message":"debug\n\nGuideline to keep in mind: one unit of work \u003d one info log","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":856,"context_line":"        :param task: A TaskManager instance."},{"line_number":857,"context_line":"        :param portgroup_obj: A changed Portgroup object."},{"line_number":858,"context_line":"        \"\"\""},{"line_number":859,"context_line":"        LOG.info("},{"line_number":860,"context_line":"            \"Portgroup %(portgroup)s (%(name)s) configuration changed - \""},{"line_number":861,"context_line":"            \"portgroup changes not currently supported by \""},{"line_number":862,"context_line":"            \"ironic-networking interface\","}],"source_content_type":"text/x-python","patch_set":10,"id":"703873f7_e4003016","line":859,"in_reply_to":"68021af0_c80ff645","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":1027,"context_line":"                    allowed_vlans\u003dallowed_vlans,"},{"line_number":1028,"context_line":"                    default_vlan\u003didle_native_vlan"},{"line_number":1029,"context_line":"                )"},{"line_number":1030,"context_line":"            except Exception as exc:"},{"line_number":1031,"context_line":"                LOG.error("},{"line_number":1032,"context_line":"                    \"Failed to reset port %(port)s for tenant network: \""},{"line_number":1033,"context_line":"                    \"%(err)s\","}],"source_content_type":"text/x-python","patch_set":10,"id":"6f7abafe_dcc9b4f3","line":1030,"updated":"2026-01-26 19:24:38.000000000","message":"except Exception","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":1027,"context_line":"                    allowed_vlans\u003dallowed_vlans,"},{"line_number":1028,"context_line":"                    default_vlan\u003didle_native_vlan"},{"line_number":1029,"context_line":"                )"},{"line_number":1030,"context_line":"            except Exception as exc:"},{"line_number":1031,"context_line":"                LOG.error("},{"line_number":1032,"context_line":"                    \"Failed to reset port %(port)s for tenant network: \""},{"line_number":1033,"context_line":"                    \"%(err)s\","}],"source_content_type":"text/x-python","patch_set":10,"id":"8a186301_176a0924","line":1030,"in_reply_to":"6f7abafe_dcc9b4f3","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":1201,"context_line":"                allowed_vlans \u003d global_allowed_vlans"},{"line_number":1202,"context_line":""},{"line_number":1203,"context_line":"            if not mode or native_vlan is None:"},{"line_number":1204,"context_line":"                LOG.info("},{"line_number":1205,"context_line":"                    \"Skipping port %(port)s: missing mode or native_vlan for \""},{"line_number":1206,"context_line":"                    \"%(network_type)s network removal.\","},{"line_number":1207,"context_line":"                    {\u0027port\u0027: port.uuid, \u0027network_type\u0027: network_type}"}],"source_content_type":"text/x-python","patch_set":10,"id":"1b7c0fe8_e62c1485","line":1204,"range":{"start_line":1204,"start_character":20,"end_line":1204,"end_character":24},"updated":"2026-01-26 19:24:38.000000000","message":"this should either be debug or warn","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":1201,"context_line":"                allowed_vlans \u003d global_allowed_vlans"},{"line_number":1202,"context_line":""},{"line_number":1203,"context_line":"            if not mode or native_vlan is None:"},{"line_number":1204,"context_line":"                LOG.info("},{"line_number":1205,"context_line":"                    \"Skipping port %(port)s: missing mode or native_vlan for \""},{"line_number":1206,"context_line":"                    \"%(network_type)s network removal.\","},{"line_number":1207,"context_line":"                    {\u0027port\u0027: port.uuid, \u0027network_type\u0027: network_type}"}],"source_content_type":"text/x-python","patch_set":10,"id":"42296cba_2c5718fa","line":1204,"range":{"start_line":1204,"start_character":20,"end_line":1204,"end_character":24},"in_reply_to":"1b7c0fe8_e62c1485","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":1232,"context_line":"                        \u0027default_vlan\u0027: idle_native_vlan"},{"line_number":1233,"context_line":"                    }"},{"line_number":1234,"context_line":"                )"},{"line_number":1235,"context_line":"            except Exception:"},{"line_number":1236,"context_line":"                # Accumulate errors to ensure that we attempt to reset each"},{"line_number":1237,"context_line":"                # port regardless of if any single port had an error."},{"line_number":1238,"context_line":"                message \u003d f\"Failed to reset {network_type} network for \"\\"}],"source_content_type":"text/x-python","patch_set":10,"id":"b1bccb8c_c1705dd2","line":1235,"updated":"2026-01-26 19:24:38.000000000","message":"except Exception","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":1232,"context_line":"                        \u0027default_vlan\u0027: idle_native_vlan"},{"line_number":1233,"context_line":"                    }"},{"line_number":1234,"context_line":"                )"},{"line_number":1235,"context_line":"            except Exception:"},{"line_number":1236,"context_line":"                # Accumulate errors to ensure that we attempt to reset each"},{"line_number":1237,"context_line":"                # port regardless of if any single port had an error."},{"line_number":1238,"context_line":"                message \u003d f\"Failed to reset {network_type} network for \"\\"}],"source_content_type":"text/x-python","patch_set":10,"id":"841d4cd7_64267301","line":1235,"in_reply_to":"b1bccb8c_c1705dd2","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"713476bfafa0ffbaea06d51e91ae0622ac235e03","unresolved":true,"context_lines":[{"line_number":1454,"context_line":"        LOG.debug(\u0027Generated network data for node %(node)s: %(links)d links\u0027,"},{"line_number":1455,"context_line":"                  {\u0027node\u0027: task.node.uuid, \u0027links\u0027: len(links)})"},{"line_number":1456,"context_line":""},{"line_number":1457,"context_line":"        return {\u0027links\u0027: links}"},{"line_number":1458,"context_line":""},{"line_number":1459,"context_line":"    def add_servicing_network(self, task):"},{"line_number":1460,"context_line":"        \"\"\"Add the servicing network to the node."}],"source_content_type":"text/x-python","patch_set":10,"id":"6dd86aee_8f4a3f51","line":1457,"updated":"2026-01-26 19:24:38.000000000","message":"may want to TODO This as it\u0027ll need enhancement for LAG","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"fc381f06a1af5ca0074e8e4357b6f484de312295","unresolved":false,"context_lines":[{"line_number":1454,"context_line":"        LOG.debug(\u0027Generated network data for node %(node)s: %(links)d links\u0027,"},{"line_number":1455,"context_line":"                  {\u0027node\u0027: task.node.uuid, \u0027links\u0027: len(links)})"},{"line_number":1456,"context_line":""},{"line_number":1457,"context_line":"        return {\u0027links\u0027: links}"},{"line_number":1458,"context_line":""},{"line_number":1459,"context_line":"    def add_servicing_network(self, task):"},{"line_number":1460,"context_line":"        \"\"\"Add the servicing network to the node."}],"source_content_type":"text/x-python","patch_set":10,"id":"b580cbe8_9793bddf","line":1457,"in_reply_to":"6dd86aee_8f4a3f51","updated":"2026-01-28 14:43:59.000000000","message":"Done","commit_id":"07a406eeedac7b3d801ce1ac62fe0ad96bd9889b"},{"author":{"_account_id":14228,"name":"Clif Houck","email":"me@clifhouck.com","username":"clif_h"},"change_message_id":"c9fc4a65ad2f29768ce670ba4af56389df3eb71e","unresolved":true,"context_lines":[{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    This network interface is designed for standalone Ironic deployments"},{"line_number":50,"context_line":"    where network configuration is either handled externally or not required."},{"line_number":51,"context_line":"    All methods are implemented as no-ops, allowing Ironic to operate without"},{"line_number":52,"context_line":"    performing any network-related actions."},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    This interface is particularly useful for:"},{"line_number":55,"context_line":"    - Testing and development environments"}],"source_content_type":"text/x-python","patch_set":11,"id":"41f06614_d82f50b9","line":52,"range":{"start_line":51,"start_character":4,"end_line":52,"end_character":43},"updated":"2026-01-28 18:56:05.000000000","message":"Is this true? Or is this hold-over from another docstring? This is from a group-GR-OSS review.","commit_id":"0da5f50c2ce8ef6a3c3f16d5c4489d38b5e4053f"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"28c0b8dd7dd2988f45e0e4cd0179eb32e577bb2a","unresolved":false,"context_lines":[{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    This network interface is designed for standalone Ironic deployments"},{"line_number":50,"context_line":"    where network configuration is either handled externally or not required."},{"line_number":51,"context_line":"    All methods are implemented as no-ops, allowing Ironic to operate without"},{"line_number":52,"context_line":"    performing any network-related actions."},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    This interface is particularly useful for:"},{"line_number":55,"context_line":"    - Testing and development environments"}],"source_content_type":"text/x-python","patch_set":11,"id":"f0aee096_2ad88025","line":52,"range":{"start_line":51,"start_character":4,"end_line":52,"end_character":43},"in_reply_to":"0d965b5d_6ddd2ceb","updated":"2026-01-30 19:31:05.000000000","message":"Done","commit_id":"0da5f50c2ce8ef6a3c3f16d5c4489d38b5e4053f"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"a5b7765e39e0fe490e4babdbd1391b63592f1aea","unresolved":true,"context_lines":[{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    This network interface is designed for standalone Ironic deployments"},{"line_number":50,"context_line":"    where network configuration is either handled externally or not required."},{"line_number":51,"context_line":"    All methods are implemented as no-ops, allowing Ironic to operate without"},{"line_number":52,"context_line":"    performing any network-related actions."},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    This interface is particularly useful for:"},{"line_number":55,"context_line":"    - Testing and development environments"}],"source_content_type":"text/x-python","patch_set":11,"id":"0d965b5d_6ddd2ceb","line":52,"range":{"start_line":51,"start_character":4,"end_line":52,"end_character":43},"in_reply_to":"41f06614_d82f50b9","updated":"2026-01-28 20:02:02.000000000","message":"yes, definitely some cut-n-paste shenanigans happening here.  Will update in a follow-up.","commit_id":"0da5f50c2ce8ef6a3c3f16d5c4489d38b5e4053f"},{"author":{"_account_id":14228,"name":"Clif Houck","email":"me@clifhouck.com","username":"clif_h"},"change_message_id":"c9fc4a65ad2f29768ce670ba4af56389df3eb71e","unresolved":true,"context_lines":[{"line_number":143,"context_line":"            return None, None, None"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        # Expected format:"},{"line_number":146,"context_line":"        # {access|trunk|hybrid}/native_vlan\u003dVLAN_ID/[allowed_vlans\u003dCSV]"},{"line_number":147,"context_line":"        try:"},{"line_number":148,"context_line":"            # TODO(alegacy): Add support for allowed_vlans"},{"line_number":149,"context_line":"            mode_part, vlan_part \u003d network_value.split(\u0027/\u0027, 1)"}],"source_content_type":"text/x-python","patch_set":11,"id":"011da30d_63925e0b","line":146,"updated":"2026-01-28 18:56:05.000000000","message":"I believe this should be a separate object that encompasses this format and handles the parsing of it. Can be a follow-up change.","commit_id":"0da5f50c2ce8ef6a3c3f16d5c4489d38b5e4053f"},{"author":{"_account_id":25437,"name":"Allain Legacy","email":"alegacy@redhat.com","username":"alegacy"},"change_message_id":"a5b7765e39e0fe490e4babdbd1391b63592f1aea","unresolved":true,"context_lines":[{"line_number":143,"context_line":"            return None, None, None"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        # Expected format:"},{"line_number":146,"context_line":"        # {access|trunk|hybrid}/native_vlan\u003dVLAN_ID/[allowed_vlans\u003dCSV]"},{"line_number":147,"context_line":"        try:"},{"line_number":148,"context_line":"            # TODO(alegacy): Add support for allowed_vlans"},{"line_number":149,"context_line":"            mode_part, vlan_part \u003d network_value.split(\u0027/\u0027, 1)"}],"source_content_type":"text/x-python","patch_set":11,"id":"d4695e95_22e2fb20","line":146,"in_reply_to":"011da30d_63925e0b","updated":"2026-01-28 20:02:02.000000000","message":"Ok, will consider in a follow-up.","commit_id":"0da5f50c2ce8ef6a3c3f16d5c4489d38b5e4053f"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"72dbce61b5652ecb5500c1d923537afad51d0022","unresolved":true,"context_lines":[{"line_number":40,"context_line":"CONF \u003d cfg.CONF"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"# Register networking configuration options"},{"line_number":43,"context_line":"ironic_networking.register_opts(CONF)"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"class IronicNetworking(base.NetworkInterface):"}],"source_content_type":"text/x-python","patch_set":12,"id":"d01075bb_230b7ce4","line":43,"range":{"start_line":43,"start_character":0,"end_line":43,"end_character":37},"updated":"2026-02-03 10:20:35.000000000","message":"Every other config initialization happens inside `ironic/conf/__init__.py`. I wonder why we have this here.","commit_id":"c5f75a924c4e7b90f581a2722da9cc49bacc61bc"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"72dbce61b5652ecb5500c1d923537afad51d0022","unresolved":true,"context_lines":[{"line_number":187,"context_line":"            if not switchport:"},{"line_number":188,"context_line":"                continue"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":"            # Get the mode and native_vlan for the network type"},{"line_number":191,"context_line":"            mode, native_vlan, ignored_allowed_vlans \u003d ("},{"line_number":192,"context_line":"                self._get_network_mode_and_vlan(task, network_type)"},{"line_number":193,"context_line":"            )"},{"line_number":194,"context_line":""},{"line_number":195,"context_line":"            # If network configuration is not set, use port\u0027s switchport info"},{"line_number":196,"context_line":"            if mode is None or native_vlan is None:"}],"source_content_type":"text/x-python","patch_set":12,"id":"20f32325_810ecf39","line":193,"range":{"start_line":190,"start_character":0,"end_line":193,"end_character":13},"updated":"2026-02-03 10:20:35.000000000","message":"Move this outside the loop since it does not depend on a port, that way we also get to return early if `port.local_link_connection`. Right now we skip to switchport retrieval even when global network config is valid.","commit_id":"c5f75a924c4e7b90f581a2722da9cc49bacc61bc"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"72dbce61b5652ecb5500c1d923537afad51d0022","unresolved":true,"context_lines":[{"line_number":375,"context_line":"        # Extract switch IDs from member ports\u0027 local_link_connection"},{"line_number":376,"context_line":"        switch_ids \u003d set()"},{"line_number":377,"context_line":"        for port in member_ports:"},{"line_number":378,"context_line":"            if (port.extra and port.extra.get(\u0027switchport\u0027)"},{"line_number":379,"context_line":"                    and port.local_link_connection):"},{"line_number":380,"context_line":"                switch_id \u003d port.local_link_connection.get(\u0027switch_id\u0027)"},{"line_number":381,"context_line":"                if switch_id:"}],"source_content_type":"text/x-python","patch_set":12,"id":"e8d63c12_a16c3450","line":378,"range":{"start_line":378,"start_character":16,"end_line":378,"end_character":59},"updated":"2026-02-03 10:20:35.000000000","message":"Why do we need these to be truthy if they are never used?","commit_id":"c5f75a924c4e7b90f581a2722da9cc49bacc61bc"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"72dbce61b5652ecb5500c1d923537afad51d0022","unresolved":true,"context_lines":[{"line_number":815,"context_line":""},{"line_number":816,"context_line":"        :param task: A TaskManager instance."},{"line_number":817,"context_line":"        :param vif_info: A dictionary of information about a VIF."},{"line_number":818,"context_line":"            It must have an \u0027id\u0027 key, whose value is a unique"},{"line_number":819,"context_line":"            identifier for that VIF."},{"line_number":820,"context_line":"        \"\"\""},{"line_number":821,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":12,"id":"e2992ac6_db33de1a","line":818,"range":{"start_line":818,"start_character":0,"end_line":818,"end_character":61},"updated":"2026-02-03 10:20:35.000000000","message":"This is not validated here. Intentional(?)","commit_id":"c5f75a924c4e7b90f581a2722da9cc49bacc61bc"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"72dbce61b5652ecb5500c1d923537afad51d0022","unresolved":true,"context_lines":[{"line_number":855,"context_line":"        \"\"\""},{"line_number":856,"context_line":"        return None"},{"line_number":857,"context_line":""},{"line_number":858,"context_line":"    def _add_tenant_networks(self, task):"},{"line_number":859,"context_line":"        \"\"\"Add tenant networks to a node."},{"line_number":860,"context_line":""},{"line_number":861,"context_line":"        This method attempts to configure the tenant network for each port"}],"source_content_type":"text/x-python","patch_set":12,"id":"45464417_67090bea","line":858,"range":{"start_line":858,"start_character":8,"end_line":858,"end_character":28},"updated":"2026-02-03 10:20:35.000000000","message":"super nit: the network setup and tear down methods overlap enough that there may be room for a utility function for those repetitive parts.","commit_id":"c5f75a924c4e7b90f581a2722da9cc49bacc61bc"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"72dbce61b5652ecb5500c1d923537afad51d0022","unresolved":true,"context_lines":[{"line_number":862,"context_line":"        on the node using only the port\u0027s switchport configuration. If the"},{"line_number":863,"context_line":"        switchport configuration is missing or incomplete, the port is skipped."},{"line_number":864,"context_line":""},{"line_number":865,"context_line":"        :param task: A TaskManager instance."},{"line_number":866,"context_line":"        \"\"\""},{"line_number":867,"context_line":"        LOG.debug(\"Adding tenant networks to node %(node)s\","},{"line_number":868,"context_line":"                  {\u0027node\u0027: task.node.uuid})"}],"source_content_type":"text/x-python","patch_set":12,"id":"5e5eedb0_9669b784","line":865,"range":{"start_line":865,"start_character":0,"end_line":865,"end_character":44},"updated":"2026-02-03 10:20:35.000000000","message":"nit: Document exception raises","commit_id":"c5f75a924c4e7b90f581a2722da9cc49bacc61bc"}]}
