)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":31746,"name":"Oleksandr Kozachenko","email":"okozachenko1203@gmail.com","username":"okozachenko"},"change_message_id":"e15fa0dcacb4318a0d88d49a2fda58cc3cd28456","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"22119873_64e641be","updated":"2026-03-02 07:32:18.000000000","message":"recheck","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"},{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"b4f4197d4aaa850e22c441db7637ad8b95d8a677","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"672824f8_6e763f09","updated":"2026-02-28 03:49:41.000000000","message":"recheck","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"},{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"296e3074160ddd11532f4ec9e8b9a1e7efc59102","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"c58bcccc_a7789333","updated":"2026-03-02 14:40:38.000000000","message":"recheck neutron.tests.functional.agent.ovn.extensions.bgp.test_bridge.BGPChassisBridgeTestCase.test_patch_port_ofport","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"}],"neutron/common/ovn/acl.py":[{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"736dc80b6fd1d6ef2bba7b0cfb13859ac0ec390c","unresolved":false,"context_lines":[{"line_number":137,"context_line":"    return match"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"def _add_acls_for_drop(pg_name, priority, log\u003dFalse, log_name\u003dNone,"},{"line_number":141,"context_line":"                       severity\u003dNone, meter_name\u003dNone):"},{"line_number":142,"context_line":"    acl_list \u003d []"},{"line_number":143,"context_line":"    for direction, p in ((\u0027from-lport\u0027, \u0027inport\u0027),"}],"source_content_type":"text/x-python","patch_set":4,"id":"b7419535_8f922135","line":140,"updated":"2026-02-26 19:54:32.000000000","message":"The existing add_acls_for_drop_port_group function created the two drop ACLs (from-lport/to-lport) for neutron_pg_drop with hardcoded log\u003dfalse and priority. Since the new per-SG drop ACLs need the exact same ACL structure but with different parameters (higher priority, log\u003dtrue, a log resource name, severity, and meter), we extract the common logic into _add_acls_for_drop and have both callers use it.\n\nadd_acls_for_log_drop_port_group is the new public function that creates per-SG drop ACLs. It’s called with the SG’s port group name (not neutron_pg_drop), the log resource name (so OVN stamps events with the right identifier), and the meter name (for rate limiting). The ACLs it creates have:\n- priority\u003d1001 (higher than neutron_pg_drop’s 1000, so they match first)\n- log\u003dtrue (so OVN generates log events for matched packets)\n- name\u003dlog_name (so the log event is attributed to the correct log resource)\n- severity\u003d\"info\" and meter\u003dmeter_name (for log classification and rate limiting)\n\nThe match pattern (inport/outport \u003d\u003d @pg_name \u0026\u0026 ip) scopes the ACL to only ports in that specific SG’s port group, which is what provides per-project isolation.","commit_id":"8d0b459dbd6340401020188e782914b6c68958a0"}],"neutron/common/ovn/constants.py":[{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"736dc80b6fd1d6ef2bba7b0cfb13859ac0ec390c","unresolved":false,"context_lines":[{"line_number":111,"context_line":"# default drop in neutron_pg_drop."},{"line_number":112,"context_line":"ACL_PRIORITY_ALLOW \u003d 1002"},{"line_number":113,"context_line":"ACL_PRIORITY_LOG_DROP \u003d 1001"},{"line_number":114,"context_line":"ACL_PRIORITY_DROP \u003d 1000"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"ACL_ACTION_DROP \u003d \u0027drop\u0027"},{"line_number":117,"context_line":"ACL_ACTION_REJECT \u003d \u0027reject\u0027"}],"source_content_type":"text/x-python","patch_set":4,"id":"d43aae4e_97da65fc","line":114,"updated":"2026-02-26 19:54:32.000000000","message":"This is the core of the fix for LP#2110087. Previously, neutron_pg_drop used priority 1001 — the same level as per-SG allow rules. Since neutron_pg_drop is a global port group shared by ALL ports across ALL projects, enabling logging on its ACLs meant that drop events from every VM in every project got stamped with a single log resource name, regardless of which project created the log resource. This made drop log events completely unusable in multi-tenant environments.\n\nBy splitting into three priority tiers:\n- 1002 (ACL_PRIORITY_ALLOW): per-SG allow rules — unchanged, these still take highest precedence\n- 1001 (ACL_PRIORITY_LOG_DROP): NEW per-SG drop ACLs created on each SG’s own port group with log\u003dtrue and the correct log resource name\n- 1000 (ACL_PRIORITY_DROP): global neutron_pg_drop — demoted, always log\u003dfalse, serves as a silent safety net\n\nOVN evaluates ACLs highest-priority-first. When a packet doesn’t match any allow rule at 1002, it hits the per-SG drop ACL at 1001 (if logging is enabled for that SG). This ACL has log\u003dtrue with the correct log resource name, so the drop event is correctly attributed to the project that owns the SG. If no per-SG drop ACL exists (no logging configured), the packet falls through to the global neutron_pg_drop at 1000 which silently drops it — preserving the existing default-deny behavior without generating any log noise.","commit_id":"8d0b459dbd6340401020188e782914b6c68958a0"}],"neutron/common/ovn/utils.py":[{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"736dc80b6fd1d6ef2bba7b0cfb13859ac0ec390c","unresolved":false,"context_lines":[{"line_number":1025,"context_line":"                \"action\": \"drop\","},{"line_number":1026,"context_line":"                \"direction\": \"to-lport\","},{"line_number":1027,"context_line":"                \"match\": \"outport \u003d\u003d @neutron_pg_drop \u0026\u0026 ip\","},{"line_number":1028,"context_line":"                \"priority\": constants.ACL_PRIORITY_DROP"},{"line_number":1029,"context_line":"            },"},{"line_number":1030,"context_line":"            \"uuid-name\": \"droptoport\""},{"line_number":1031,"context_line":"        }, {"}],"source_content_type":"text/x-python","patch_set":4,"id":"b94a806f_46d6a838","line":1028,"updated":"2026-02-26 19:54:32.000000000","message":"create_neutron_pg_drop() builds the raw ovsdb transaction that creates the neutron_pg_drop port group during initial OVN bootstrap (before the normal IDL connection is established). It was using a hardcoded priority of 1001. Updated to use the ACL_PRIORITY_DROP constant (now 1000) so that new deployments immediately get the correct priority. This is complemented by the maintenance task (update_neutron_pg_drop_priority) which handles existing deployments that already have neutron_pg_drop at 1001.","commit_id":"8d0b459dbd6340401020188e782914b6c68958a0"}],"neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/maintenance.py":[{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"736dc80b6fd1d6ef2bba7b0cfb13859ac0ec390c","unresolved":false,"context_lines":[{"line_number":1119,"context_line":""},{"line_number":1120,"context_line":"        raise periodics.NeverAgain()"},{"line_number":1121,"context_line":""},{"line_number":1122,"context_line":"    @has_lock_periodic("},{"line_number":1123,"context_line":"        periodic_run_limit\u003dovn_const.MAINTENANCE_TASK_RETRY_LIMIT,"},{"line_number":1124,"context_line":"        spacing\u003dovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,"},{"line_number":1125,"context_line":"        run_immediately\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":4,"id":"a6658e01_8d14d85c","line":1122,"updated":"2026-02-26 19:54:32.000000000","message":"This is a one-shot maintenance task (raises NeverAgain after completion) for existing deployments upgrading to this version. Before this change, neutron_pg_drop ACLs were created at priority 1001. The new per-SG drop ACLs also need priority 1001 to work correctly — they must match BEFORE neutron_pg_drop so that drops are attributed to the correct SG/project.\n\nIf we only changed the constant without migrating existing ACLs, deployed clouds would have both neutron_pg_drop and per-SG drop ACLs at the same priority 1001. Since neutron_pg_drop contains ALL ports, its ACL would match just as well as the per-SG one, and OVN’s behavior with same-priority ACLs in different port groups would be unpredictable.\n\nThis task looks up neutron_pg_drop, finds any ACLs with action\u003ddrop that aren’t at the expected priority (1000), and updates them in a single transaction. It runs once on startup and never again, so there’s no ongoing performance impact.","commit_id":"8d0b459dbd6340401020188e782914b6c68958a0"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"e7fa68595bd76e2497cf7b89cb323da2e3b0a478","unresolved":true,"context_lines":[{"line_number":1210,"context_line":"        periodic_run_limit\u003dovn_const.MAINTENANCE_TASK_RETRY_LIMIT,"},{"line_number":1211,"context_line":"        spacing\u003dovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,"},{"line_number":1212,"context_line":"        run_immediately\u003dTrue)"},{"line_number":1213,"context_line":"    def update_neutron_pg_drop_priority(self):"},{"line_number":1214,"context_line":"        \"\"\"Ensure neutron_pg_drop ACLs are at the expected priority."},{"line_number":1215,"context_line":""},{"line_number":1216,"context_line":"        The global neutron_pg_drop ACLs must be at ACL_PRIORITY_DROP to"}],"source_content_type":"text/x-python","patch_set":9,"id":"f3b4a671_6edb5b25","line":1213,"range":{"start_line":1213,"start_character":8,"end_line":1213,"end_character":39},"updated":"2026-03-09 08:17:04.000000000","message":"This method should have an expiry date, once we can ensure all drop PG have been created with priority\u003d1000. You should add this message:\n```\n# TODO(nmaser): to remove in G+4 (2028.1) cycle (2nd next SLURP release)\n```","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"},{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"c42c0eee1733485fafdb5df1be84e523e053a866","unresolved":false,"context_lines":[{"line_number":1210,"context_line":"        periodic_run_limit\u003dovn_const.MAINTENANCE_TASK_RETRY_LIMIT,"},{"line_number":1211,"context_line":"        spacing\u003dovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,"},{"line_number":1212,"context_line":"        run_immediately\u003dTrue)"},{"line_number":1213,"context_line":"    def update_neutron_pg_drop_priority(self):"},{"line_number":1214,"context_line":"        \"\"\"Ensure neutron_pg_drop ACLs are at the expected priority."},{"line_number":1215,"context_line":""},{"line_number":1216,"context_line":"        The global neutron_pg_drop ACLs must be at ACL_PRIORITY_DROP to"}],"source_content_type":"text/x-python","patch_set":9,"id":"d295a3a7_2c3a56a9","line":1213,"range":{"start_line":1213,"start_character":8,"end_line":1213,"end_character":39},"in_reply_to":"f3b4a671_6edb5b25","updated":"2026-04-08 21:42:05.000000000","message":"Done","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"e7fa68595bd76e2497cf7b89cb323da2e3b0a478","unresolved":true,"context_lines":[{"line_number":1223,"context_line":"        try:"},{"line_number":1224,"context_line":"            pg \u003d self._nb_idl.lookup("},{"line_number":1225,"context_line":"                \"Port_Group\", ovn_const.OVN_DROP_PORT_GROUP_NAME)"},{"line_number":1226,"context_line":"        except Exception:"},{"line_number":1227,"context_line":"            raise periodics.NeverAgain()"},{"line_number":1228,"context_line":""},{"line_number":1229,"context_line":"        for acl in pg.acls:"}],"source_content_type":"text/x-python","patch_set":9,"id":"66ee0285_f65b703c","line":1226,"range":{"start_line":1226,"start_character":15,"end_line":1226,"end_character":24},"updated":"2026-03-09 08:17:04.000000000","message":"1) Is unlikely that this happens. We always create de drop port PG. If that happens, we should log an error.\n2) If we are using lookup, better to use `default\u003dNone` and check if the value is None","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"},{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"c42c0eee1733485fafdb5df1be84e523e053a866","unresolved":false,"context_lines":[{"line_number":1223,"context_line":"        try:"},{"line_number":1224,"context_line":"            pg \u003d self._nb_idl.lookup("},{"line_number":1225,"context_line":"                \"Port_Group\", ovn_const.OVN_DROP_PORT_GROUP_NAME)"},{"line_number":1226,"context_line":"        except Exception:"},{"line_number":1227,"context_line":"            raise periodics.NeverAgain()"},{"line_number":1228,"context_line":""},{"line_number":1229,"context_line":"        for acl in pg.acls:"}],"source_content_type":"text/x-python","patch_set":9,"id":"4bcbe3cf_9c8af6bd","line":1226,"range":{"start_line":1226,"start_character":15,"end_line":1226,"end_character":24},"in_reply_to":"66ee0285_f65b703c","updated":"2026-04-08 21:42:05.000000000","message":"Done","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"}],"neutron/services/logapi/drivers/ovn/driver.py":[{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"736dc80b6fd1d6ef2bba7b0cfb13859ac0ec390c","unresolved":false,"context_lines":[{"line_number":199,"context_line":"            actions_enabled \u003d self._acl_actions_enabled(log_obj)"},{"line_number":200,"context_line":"            log_name \u003d utils.ovn_name(log_obj.id)"},{"line_number":201,"context_line":"            self._set_acls_log(pgs, context, ovn_txn, actions_enabled,"},{"line_number":202,"context_line":"                               log_name)"},{"line_number":203,"context_line":"            if log_obj.enabled:"},{"line_number":204,"context_line":"                self._create_sg_drop_acls(context, log_obj, ovn_txn,"},{"line_number":205,"context_line":"                                          log_name)"}],"source_content_type":"text/x-python","patch_set":4,"id":"42dd4806_ca3e881a","line":202,"updated":"2026-02-26 19:54:32.000000000","message":"When a log resource is deleted and other log resources still exist for the same SG, _update_log_objs re-processes the remaining log objects to ensure their ACL log flags are correct. Previously it only called _set_acls_log (which toggles log flags on existing ACLs like the allow rules).\n\nThe problem: when a DROP log resource is deleted, _remove_sg_drop_acls deletes the per-SG drop ACLs entirely. If another remaining log resource also needs DROP logging (e.g., an ALL event log), those per-SG drop ACLs need to be recreated with the remaining log resource’s name. Without this addition, deleting one DROP log would silently break drop logging for all other log resources on the same SG.\n\nThe `if log_obj.enabled` guard ensures we only create drop ACLs for enabled log objects — disabled ones should not have active logging ACLs.","commit_id":"8d0b459dbd6340401020188e782914b6c68958a0"},{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"736dc80b6fd1d6ef2bba7b0cfb13859ac0ec390c","unresolved":false,"context_lines":[{"line_number":236,"context_line":"                return pgs"},{"line_number":237,"context_line":"            except idlutils.RowNotFound:"},{"line_number":238,"context_line":"                pass"},{"line_number":239,"context_line":"        return self._get_sg_port_groups(context, log_obj)"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"    def _get_sg_port_groups(self, context, log_obj):"},{"line_number":242,"context_line":"        \"\"\"Get port groups for the security groups targeted by a log object.\"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"34723da2_5e089410","line":239,"updated":"2026-02-26 19:54:32.000000000","message":"This is the root cause fix for LP#2110087. Previously, _pgs_from_log_obj had this logic for per-SG log resources:\n\n1. Look up neutron_pg_drop and add it to the port groups list (for DROP/ALL events)\n2. Then also look up the SG’s own port group and add it\n\nThis meant that when _set_acls_log processed these port groups, it would enable logging on neutron_pg_drop’s ACLs — a global port group containing every port in the deployment. Every VM’s drop events would then get stamped with this one log resource’s name, regardless of which project the VM belonged to. A tenant enabling drop logging on their SG would see drops from every other tenant’s VMs in their logs.\n\nThe fix is simple: when a resource_id or target_id is specified, only return the SG’s own port groups. Drop logging for these specific SGs is now handled by the new per-SG drop ACLs (_create_sg_drop_acls) at priority 1001, which are scoped to only that SG’s port group.\n\nThe global neutron_pg_drop path is preserved only for the unscoped case (no resource_id, no target_id) — e.g., an admin requesting global drop logging without targeting any specific SG.","commit_id":"8d0b459dbd6340401020188e782914b6c68958a0"},{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"736dc80b6fd1d6ef2bba7b0cfb13859ac0ec390c","unresolved":false,"context_lines":[{"line_number":238,"context_line":"                pass"},{"line_number":239,"context_line":"        return self._get_sg_port_groups(context, log_obj)"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"    def _get_sg_port_groups(self, context, log_obj):"},{"line_number":242,"context_line":"        \"\"\"Get port groups for the security groups targeted by a log object.\"\"\""},{"line_number":243,"context_line":"        pgs \u003d []"},{"line_number":244,"context_line":"        if log_obj.resource_id:"}],"source_content_type":"text/x-python","patch_set":4,"id":"ef1912b6_6fcf8d26","line":241,"updated":"2026-02-26 19:54:32.000000000","message":"Extracted from the old _pgs_from_log_obj to avoid duplicating the resource_id vs target_id lookup logic. This method resolves a log object to its targeted SG port groups:\n- If resource_id is set: looks up that specific SG’s port group directly\n- If target_id is set: finds all SGs attached to that port, then looks up each SG’s port group\n\nIt’s now used by three callers:\n1. _pgs_from_log_obj — to determine which port groups need their existing ACL log flags updated\n2. _create_sg_drop_acls — to know which port groups need new per-SG drop ACLs\n3. _remove_sg_drop_acls — to know which port groups need per-SG drop ACLs removed\n\nPreviously this logic was inline in _pgs_from_log_obj and interleaved with the neutron_pg_drop lookup, making it harder to reuse.","commit_id":"8d0b459dbd6340401020188e782914b6c68958a0"},{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"736dc80b6fd1d6ef2bba7b0cfb13859ac0ec390c","unresolved":false,"context_lines":[{"line_number":265,"context_line":"                    pass"},{"line_number":266,"context_line":"        return pgs"},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"    def _create_sg_drop_acls(self, context, log_obj, ovn_txn, log_name):"},{"line_number":269,"context_line":"        \"\"\"Create per-SG drop ACLs for network log attribution."},{"line_number":270,"context_line":""},{"line_number":271,"context_line":"        When logging DROP events for a specific security group, we create"}],"source_content_type":"text/x-python","patch_set":4,"id":"a34e7180_94e02cc0","line":268,"updated":"2026-02-26 19:54:32.000000000","message":"These two methods manage the lifecycle of per-SG drop ACLs — the new mechanism for correct drop event attribution.\n\n_create_sg_drop_acls:\n- Only acts on DROP and ALL events (ACCEPT-only logs don’t need drop ACLs)\n- Resolves the log object to its SG port groups via _get_sg_port_groups\n- Creates two ACLs per SG port group (from-lport and to-lport) at priority 1001 with log\u003dtrue\n- Uses may_exist\u003dTrue so it’s idempotent (safe to call multiple times, e.g., from _update_log_objs)\n- The ACL match pattern (inport/outport \u003d\u003d @pg_name \u0026\u0026 ip) scopes drops to only ports in that SG\n\n_remove_sg_drop_acls:\n- Deletes the per-SG drop ACLs when logging is disabled or the log resource is removed\n- Must specify both priority AND match together in pg_acl_del — this is an ovsdbapp requirement; passing priority with match\u003dNone raises TypeError (\"Must specify priority and match together\")\n- The match string must exactly match what was used during creation","commit_id":"8d0b459dbd6340401020188e782914b6c68958a0"},{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"736dc80b6fd1d6ef2bba7b0cfb13859ac0ec390c","unresolved":false,"context_lines":[{"line_number":312,"context_line":"            self._ovn_client.create_ovn_fair_meter(self.meter_name,"},{"line_number":313,"context_line":"                                                   txn\u003dovn_txn)"},{"line_number":314,"context_line":"            self._set_acls_log(pgs, context, ovn_txn, actions_enabled,"},{"line_number":315,"context_line":"                               log_name)"},{"line_number":316,"context_line":"            self._create_sg_drop_acls(context, log_obj, ovn_txn, log_name)"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"    def create_log_precommit(self, context, log_obj):"}],"source_content_type":"text/x-python","patch_set":4,"id":"132b4a62_8410d3b0","line":315,"updated":"2026-02-26 19:54:32.000000000","message":"Each lifecycle method now manages per-SG drop ACLs alongside the existing ACL log flag updates:\n\n- create_log: After setting log flags on existing SG ACLs via _set_acls_log, also creates per-SG drop ACLs so drop events are logged with the correct resource name from the start.\n\n- update_log: When a log resource is enabled, creates per-SG drop ACLs. When disabled, removes them. This is done inside the same transaction as the log flag updates for atomicity.\n\n- delete_log (last log): Removes per-SG drop ACLs as part of full cleanup. This is in the \"no remaining log objects\" path where we also remove the meter.\n\n- delete_log (non-last log): Removes per-SG drop ACLs for the deleted log, then _update_log_objs recreates them for any remaining enabled log objects that need DROP logging. The two-step approach (remove then recreate) ensures the ACLs get the correct log resource name from the remaining log object.","commit_id":"8d0b459dbd6340401020188e782914b6c68958a0"},{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"7b963afe7e0345d678f4ef724050d18d779bfe57","unresolved":false,"context_lines":[{"line_number":177,"context_line":"                # Don\u0027t claim ACLs whose action is not relevant to this"},{"line_number":178,"context_line":"                # log object; otherwise a DROP log would claim the allow"},{"line_number":179,"context_line":"                # ACLs and block a later ALL/ACCEPT log from updating them."},{"line_number":180,"context_line":"                if not acl.name and acl.action not in actions_enabled:"},{"line_number":181,"context_line":"                    continue"},{"line_number":182,"context_line":"                columns \u003d {"},{"line_number":183,"context_line":"                    \u0027log\u0027: acl.action in actions_enabled,"}],"source_content_type":"text/x-python","patch_set":5,"id":"50d7593c_72c57771","line":180,"updated":"2026-02-26 21:30:29.000000000","message":"New guard: prevents a log object from claiming ACLs that are irrelevant to its event type.\n\nPreviously, a DROP event log would process all ACLs in the SG port group (including allow ACLs), set log\u003dFalse on them, but also stamp name\u003dlog_name — effectively \"claiming\" them. A subsequent ALL or ACCEPT log would then see those allow ACLs as owned by a different log (name !\u003d its own) and skip them, leaving allow ACLs permanently unlogged.\n\nWith this guard, unclaimed ACLs whose action doesn\u0027t match the log\u0027s actions_enabled set are skipped entirely. The allow ACLs remain unclaimed and available for a later ALL/ACCEPT log to pick up.\n\nNote: ACLs already claimed by this log (acl.name \u003d\u003d log_name) are still processed — this is needed for the disable path where actions_enabled is empty but we still need to set log\u003dFalse on our owned ACLs.","commit_id":"39f434931b3efadebd4ad585b9068b722d7b12ca"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"e7fa68595bd76e2497cf7b89cb323da2e3b0a478","unresolved":true,"context_lines":[{"line_number":202,"context_line":"        for log_obj in log_objs:"},{"line_number":203,"context_line":"            pgs \u003d self._pgs_from_log_obj(context, log_obj)"},{"line_number":204,"context_line":"            actions_enabled \u003d self._acl_actions_enabled(log_obj)"},{"line_number":205,"context_line":"            log_name \u003d utils.ovn_name(log_obj.id)"},{"line_number":206,"context_line":"            self._set_acls_log(pgs, context, ovn_txn, actions_enabled,"},{"line_number":207,"context_line":"                               log_name)"},{"line_number":208,"context_line":"            if log_obj.enabled:"}],"source_content_type":"text/x-python","patch_set":9,"id":"b688a72d_39fdbb89","line":205,"range":{"start_line":205,"start_character":12,"end_line":205,"end_character":49},"updated":"2026-03-09 08:17:04.000000000","message":"nitty nit: we can define it before the loop, only once","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"},{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"c42c0eee1733485fafdb5df1be84e523e053a866","unresolved":false,"context_lines":[{"line_number":202,"context_line":"        for log_obj in log_objs:"},{"line_number":203,"context_line":"            pgs \u003d self._pgs_from_log_obj(context, log_obj)"},{"line_number":204,"context_line":"            actions_enabled \u003d self._acl_actions_enabled(log_obj)"},{"line_number":205,"context_line":"            log_name \u003d utils.ovn_name(log_obj.id)"},{"line_number":206,"context_line":"            self._set_acls_log(pgs, context, ovn_txn, actions_enabled,"},{"line_number":207,"context_line":"                               log_name)"},{"line_number":208,"context_line":"            if log_obj.enabled:"}],"source_content_type":"text/x-python","patch_set":9,"id":"cade299c_86e93957","line":205,"range":{"start_line":205,"start_character":12,"end_line":205,"end_character":49},"in_reply_to":"b688a72d_39fdbb89","updated":"2026-04-08 21:42:05.000000000","message":"Done","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"e7fa68595bd76e2497cf7b89cb323da2e3b0a478","unresolved":true,"context_lines":[{"line_number":279,"context_line":"        attributed to the specific security group\u0027s log resource."},{"line_number":280,"context_line":"        \"\"\""},{"line_number":281,"context_line":"        if log_obj.event not in (log_const.DROP_EVENT, log_const.ALL_EVENT,"},{"line_number":282,"context_line":"                                 None):"},{"line_number":283,"context_line":"            return"},{"line_number":284,"context_line":"        sg_pgs \u003d self._get_sg_port_groups(context, log_obj)"},{"line_number":285,"context_line":"        if not sg_pgs:"}],"source_content_type":"text/x-python","patch_set":9,"id":"6109acd0_0c67778c","line":282,"range":{"start_line":282,"start_character":33,"end_line":282,"end_character":37},"updated":"2026-03-09 08:17:04.000000000","message":"I\u0027m missing here: why None?","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"},{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"c42c0eee1733485fafdb5df1be84e523e053a866","unresolved":false,"context_lines":[{"line_number":279,"context_line":"        attributed to the specific security group\u0027s log resource."},{"line_number":280,"context_line":"        \"\"\""},{"line_number":281,"context_line":"        if log_obj.event not in (log_const.DROP_EVENT, log_const.ALL_EVENT,"},{"line_number":282,"context_line":"                                 None):"},{"line_number":283,"context_line":"            return"},{"line_number":284,"context_line":"        sg_pgs \u003d self._get_sg_port_groups(context, log_obj)"},{"line_number":285,"context_line":"        if not sg_pgs:"}],"source_content_type":"text/x-python","patch_set":9,"id":"a9fcc0ee_ea264464","line":282,"range":{"start_line":282,"start_character":33,"end_line":282,"end_character":37},"in_reply_to":"6109acd0_0c67778c","updated":"2026-04-08 21:42:05.000000000","message":"Done","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"e7fa68595bd76e2497cf7b89cb323da2e3b0a478","unresolved":true,"context_lines":[{"line_number":306,"context_line":"        \"\"\"Check if other enabled logs still need per-SG drop ACLs.\"\"\""},{"line_number":307,"context_line":"        drop_events \u003d (log_const.DROP_EVENT, log_const.ALL_EVENT, None)"},{"line_number":308,"context_line":"        for log in self._get_logs(context):"},{"line_number":309,"context_line":"            if log.id \u003d\u003d log_obj.id or not log.enabled:"},{"line_number":310,"context_line":"                continue"},{"line_number":311,"context_line":"            if log.event not in drop_events:"},{"line_number":312,"context_line":"                continue"},{"line_number":313,"context_line":"            if (not log.resource_id or not log_obj.resource_id or"},{"line_number":314,"context_line":"                    log.resource_id \u003d\u003d log_obj.resource_id):"},{"line_number":315,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":9,"id":"675e5f26_81e1f4df","line":312,"range":{"start_line":309,"start_character":12,"end_line":312,"end_character":24},"updated":"2026-03-09 08:17:04.000000000","message":"We should do this filtering in the SQL query","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"},{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"c42c0eee1733485fafdb5df1be84e523e053a866","unresolved":false,"context_lines":[{"line_number":306,"context_line":"        \"\"\"Check if other enabled logs still need per-SG drop ACLs.\"\"\""},{"line_number":307,"context_line":"        drop_events \u003d (log_const.DROP_EVENT, log_const.ALL_EVENT, None)"},{"line_number":308,"context_line":"        for log in self._get_logs(context):"},{"line_number":309,"context_line":"            if log.id \u003d\u003d log_obj.id or not log.enabled:"},{"line_number":310,"context_line":"                continue"},{"line_number":311,"context_line":"            if log.event not in drop_events:"},{"line_number":312,"context_line":"                continue"},{"line_number":313,"context_line":"            if (not log.resource_id or not log_obj.resource_id or"},{"line_number":314,"context_line":"                    log.resource_id \u003d\u003d log_obj.resource_id):"},{"line_number":315,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":9,"id":"7559fd2a_5b57e46e","line":312,"range":{"start_line":309,"start_character":12,"end_line":312,"end_character":24},"in_reply_to":"675e5f26_81e1f4df","updated":"2026-04-08 21:42:05.000000000","message":"Done","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"e7fa68595bd76e2497cf7b89cb323da2e3b0a478","unresolved":true,"context_lines":[{"line_number":311,"context_line":"            if log.event not in drop_events:"},{"line_number":312,"context_line":"                continue"},{"line_number":313,"context_line":"            if (not log.resource_id or not log_obj.resource_id or"},{"line_number":314,"context_line":"                    log.resource_id \u003d\u003d log_obj.resource_id):"},{"line_number":315,"context_line":"                return True"},{"line_number":316,"context_line":"        return False"},{"line_number":317,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"3fb997d7_2f190e7f","line":314,"range":{"start_line":314,"start_character":20,"end_line":314,"end_character":58},"updated":"2026-03-09 08:17:04.000000000","message":"ditto","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"},{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"c42c0eee1733485fafdb5df1be84e523e053a866","unresolved":false,"context_lines":[{"line_number":311,"context_line":"            if log.event not in drop_events:"},{"line_number":312,"context_line":"                continue"},{"line_number":313,"context_line":"            if (not log.resource_id or not log_obj.resource_id or"},{"line_number":314,"context_line":"                    log.resource_id \u003d\u003d log_obj.resource_id):"},{"line_number":315,"context_line":"                return True"},{"line_number":316,"context_line":"        return False"},{"line_number":317,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"f5805dd3_6e91346e","line":314,"range":{"start_line":314,"start_character":20,"end_line":314,"end_character":58},"in_reply_to":"3fb997d7_2f190e7f","updated":"2026-04-08 21:42:05.000000000","message":"Done","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"6eb7ac86fe5f092d0d341b037ca6843e5a46a7ee","unresolved":true,"context_lines":[{"line_number":327,"context_line":"            log_filters \u003d [{**filters, \u0027resource_id\u0027: None},"},{"line_number":328,"context_line":"                           {**filters, \u0027resource_id\u0027: log_obj.resource_id}]"},{"line_number":329,"context_line":""},{"line_number":330,"context_line":"        for log_filter in log_filters:"},{"line_number":331,"context_line":"            for log in self._get_logs_with_events(context, drop_events,"},{"line_number":332,"context_line":"                                                  **log_filter):"},{"line_number":333,"context_line":"                if log.id !\u003d log_obj.id:"}],"source_content_type":"text/x-python","patch_set":16,"id":"6ec86e60_7aebb021","line":330,"range":{"start_line":330,"start_character":8,"end_line":330,"end_character":38},"updated":"2026-05-07 09:00:01.000000000","message":"nit: both this method and `_get_logs_with_events` are not optimized.\nRight now, this code is iterating over:\n* drop_events \u003d (log_const.DROP_EVENT, log_const.ALL_EVENT), inside `_get_logs_with_events`\n* resource_id \u003d None, log_obj.resource_id\n\nIt is possible to make a single query with:\n* event \u003d [log_const.DROP_EVENT, log_const.ALL_EVEN]\n* filters \u003d [None, log_obj.resource_id]\n\nIf this query return any log that matches `log.id !\u003d log_obj.id` (current check), it can return True.","commit_id":"339fc0bf37973431e21cdcc9fdcd84c4c4242ba1"}],"neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_resources.py":[{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"736dc80b6fd1d6ef2bba7b0cfb13859ac0ec390c","unresolved":false,"context_lines":[{"line_number":855,"context_line":"        expected_acls_with_sg_ps_enabled \u003d ["},{"line_number":856,"context_line":"            {\u0027match\u0027: \u0027inport \u003d\u003d @neutron_pg_drop \u0026\u0026 ip\u0027,"},{"line_number":857,"context_line":"             \u0027action\u0027: \u0027drop\u0027,"},{"line_number":858,"context_line":"             \u0027priority\u0027: 1000,"},{"line_number":859,"context_line":"             \u0027direction\u0027: \u0027from-lport\u0027},"},{"line_number":860,"context_line":"            {\u0027match\u0027: \u0027outport \u003d\u003d @neutron_pg_drop \u0026\u0026 ip\u0027,"},{"line_number":861,"context_line":"             \u0027action\u0027: \u0027drop\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"c2eb4829_19488e92","line":858,"updated":"2026-02-26 19:54:32.000000000","message":"These functional tests in test_ovn_db_resources.py and the unit tests in test_acl.py / test_ovn_db_sync.py verify the ACLs created for neutron_pg_drop and ports. All had the old priority 1001 hardcoded in their expected ACL dictionaries. Updated to 1000 to match ACL_PRIORITY_DROP.\n\nThese are purely mechanical changes — the test logic is unchanged, only the expected priority value is updated to reflect the demotion of neutron_pg_drop from 1001 to 1000.","commit_id":"8d0b459dbd6340401020188e782914b6c68958a0"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"e7fa68595bd76e2497cf7b89cb323da2e3b0a478","unresolved":true,"context_lines":[{"line_number":892,"context_line":"        expected_acls_with_sg_ps_enabled \u003d ["},{"line_number":893,"context_line":"            {\u0027match\u0027: \u0027inport \u003d\u003d @neutron_pg_drop \u0026\u0026 ip\u0027,"},{"line_number":894,"context_line":"             \u0027action\u0027: \u0027drop\u0027,"},{"line_number":895,"context_line":"             \u0027priority\u0027: 1000,"},{"line_number":896,"context_line":"             \u0027direction\u0027: \u0027from-lport\u0027},"},{"line_number":897,"context_line":"            {\u0027match\u0027: \u0027outport \u003d\u003d @neutron_pg_drop \u0026\u0026 ip\u0027,"},{"line_number":898,"context_line":"             \u0027action\u0027: \u0027drop\u0027,"}],"source_content_type":"text/x-python","patch_set":9,"id":"47fe761a_da571707","line":895,"range":{"start_line":895,"start_character":25,"end_line":895,"end_character":29},"updated":"2026-03-09 08:17:04.000000000","message":"ww should be using here the constant too","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"},{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"c42c0eee1733485fafdb5df1be84e523e053a866","unresolved":false,"context_lines":[{"line_number":892,"context_line":"        expected_acls_with_sg_ps_enabled \u003d ["},{"line_number":893,"context_line":"            {\u0027match\u0027: \u0027inport \u003d\u003d @neutron_pg_drop \u0026\u0026 ip\u0027,"},{"line_number":894,"context_line":"             \u0027action\u0027: \u0027drop\u0027,"},{"line_number":895,"context_line":"             \u0027priority\u0027: 1000,"},{"line_number":896,"context_line":"             \u0027direction\u0027: \u0027from-lport\u0027},"},{"line_number":897,"context_line":"            {\u0027match\u0027: \u0027outport \u003d\u003d @neutron_pg_drop \u0026\u0026 ip\u0027,"},{"line_number":898,"context_line":"             \u0027action\u0027: \u0027drop\u0027,"}],"source_content_type":"text/x-python","patch_set":9,"id":"2ea73dcc_13e28d03","line":895,"range":{"start_line":895,"start_character":25,"end_line":895,"end_character":29},"in_reply_to":"47fe761a_da571707","updated":"2026-04-08 21:42:05.000000000","message":"Done","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"}],"neutron/tests/functional/services/logapi/drivers/ovn/test_driver.py":[{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"736dc80b6fd1d6ef2bba7b0cfb13859ac0ec390c","unresolved":false,"context_lines":[{"line_number":150,"context_line":"            self.assertEqual(is_enabled, acl.log)"},{"line_number":151,"context_line":"        return acls"},{"line_number":152,"context_line":""},{"line_number":153,"context_line":"    def _check_sg_drop_acls(self, sg_id, is_enabled\u003dTrue):"},{"line_number":154,"context_line":"        \"\"\"Check per-SG drop ACLs at LOG_DROP priority on the SG port group.\"\"\""},{"line_number":155,"context_line":"        pg \u003d self.nb_api.get_port_group(utils.ovn_port_group_name(sg_id))"},{"line_number":156,"context_line":"        drop_acls \u003d [acl for acl in pg.acls"}],"source_content_type":"text/x-python","patch_set":4,"id":"2eb9300b_bd4d988f","line":153,"updated":"2026-02-26 19:54:32.000000000","message":"The existing _check_acl_log_drop verified that neutron_pg_drop’s ACLs had the expected log state. With the new per-SG approach, when a log resource targets a specific SG, we no longer touch neutron_pg_drop — so checking its ACLs would not reflect the actual logging state.\n\n_check_sg_drop_acls is the new helper that looks at the SG’s own port group and filters for ACLs at ACL_PRIORITY_LOG_DROP (1001) with action\u003ddrop — these are the per-SG drop ACLs created by _create_sg_drop_acls. When is_enabled\u003dTrue, it asserts they exist and have log\u003dTrue. When is_enabled\u003dFalse, it asserts any remaining drop ACLs have log\u003dFalse (or that none exist at all — after deletion the ACLs are fully removed, not just disabled, so an empty list passes the check).\n\nThe sg\u003d parameter on _check_acl_log_drop provides a clean migration path: tests that use global logging (no specific SG) continue checking neutron_pg_drop as before, while per-SG tests now check the correct port group. All calls in _add_logs_then_remove, test_events_one_sg, and test_disable_logs now pass sg\u003d since they target specific security groups.","commit_id":"8d0b459dbd6340401020188e782914b6c68958a0"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"e7fa68595bd76e2497cf7b89cb323da2e3b0a478","unresolved":true,"context_lines":[{"line_number":162,"context_line":"            for acl in drop_acls:"},{"line_number":163,"context_line":"                self.assertTrue(acl.log)"},{"line_number":164,"context_line":"        else:"},{"line_number":165,"context_line":"            for acl in drop_acls:"},{"line_number":166,"context_line":"                self.assertFalse(acl.log)"},{"line_number":167,"context_line":"        return drop_acls"},{"line_number":168,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"78857e87_5d2d0e78","line":165,"range":{"start_line":165,"start_character":12,"end_line":165,"end_character":33},"updated":"2026-03-09 08:17:04.000000000","message":"`drop_acls` should be empty","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"},{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"c42c0eee1733485fafdb5df1be84e523e053a866","unresolved":false,"context_lines":[{"line_number":162,"context_line":"            for acl in drop_acls:"},{"line_number":163,"context_line":"                self.assertTrue(acl.log)"},{"line_number":164,"context_line":"        else:"},{"line_number":165,"context_line":"            for acl in drop_acls:"},{"line_number":166,"context_line":"                self.assertFalse(acl.log)"},{"line_number":167,"context_line":"        return drop_acls"},{"line_number":168,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"8ec51e83_d10500af","line":165,"range":{"start_line":165,"start_character":12,"end_line":165,"end_character":33},"in_reply_to":"78857e87_5d2d0e78","updated":"2026-04-08 21:42:05.000000000","message":"Done","commit_id":"eab9f8ff00c4a970c749880a070acab931df69b1"}],"neutron/tests/unit/services/logapi/drivers/ovn/test_driver.py":[{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"736dc80b6fd1d6ef2bba7b0cfb13859ac0ec390c","unresolved":false,"context_lines":[{"line_number":140,"context_line":""},{"line_number":141,"context_line":"    def _fake_pg(self, **kwargs):"},{"line_number":142,"context_line":"        pg_dict \u003d self._fake_pg_dict(**kwargs)"},{"line_number":143,"context_line":"        pg_name \u003d pg_dict.pop(\u0027name\u0027, None)"},{"line_number":144,"context_line":"        pg \u003d mock.Mock(**pg_dict)"},{"line_number":145,"context_line":"        pg.name \u003d pg_name"},{"line_number":146,"context_line":"        return pg"}],"source_content_type":"text/x-python","patch_set":4,"id":"b66e18ae_7d8d1249","line":143,"updated":"2026-02-26 19:54:32.000000000","message":"This fixes a subtle Python mock pitfall. mock.Mock(name\u003d\u0027foo\u0027) does NOT set an attribute called \"name\" — it sets the mock’s internal display name (used in repr/str). So mock.Mock(name\u003d\u0027pg_name\u0027).name returns \u003cMock name\u003d\u0027pg_name.name\u0027 id\u003d\u0027...\u0027\u003e, not the string \u0027pg_name\u0027.\n\nThis was causing silent test issues: comparisons like pg.name \u003d\u003d \u0027some_string\u0027 would evaluate to a Mock object (truthy), so assertions wouldn’t fail even when the logic was wrong. The fix is to create the mock first, then explicitly set pg.name \u003d pg_name as a regular attribute.\n\nThis is a well-known mock gotcha because Mock.__init__ uses name\u003d for its own purposes. Other reserved mock kwargs include spec, wraps, side_effect, etc.","commit_id":"8d0b459dbd6340401020188e782914b6c68958a0"},{"author":{"_account_id":1004,"name":"Mohammed Naser","email":"mnaser@vexxhost.com","username":"mnaser"},"change_message_id":"736dc80b6fd1d6ef2bba7b0cfb13859ac0ec390c","unresolved":false,"context_lines":[{"line_number":340,"context_line":"            self._log_driver.add_label_related(neutron_acl, self.context)"},{"line_number":341,"context_line":"            self.assertNotEqual(neutron_acl[\u0027label\u0027], 0)"},{"line_number":342,"context_line":""},{"line_number":343,"context_line":"    def test__get_sg_port_groups_with_resource_id(self):"},{"line_number":344,"context_line":"        sg_id \u003d uuidutils.generate_uuid()"},{"line_number":345,"context_line":"        pg_name \u003d ovn_utils.ovn_port_group_name(sg_id)"},{"line_number":346,"context_line":"        pg \u003d self._fake_pg(name\u003dpg_name,"}],"source_content_type":"text/x-python","patch_set":4,"id":"4e1eac43_d7de91b9","line":343,"updated":"2026-02-26 19:54:32.000000000","message":"This test was previously named test__pgs_from_log_obj_drop_with_resource_returns_pg_drop and verified the OLD (buggy) behavior: that _pgs_from_log_obj would return neutron_pg_drop when a resource_id was set with DROP event. It had to mock two lookup calls (one for neutron_pg_drop, one that raised RowNotFound for the SG PG).\n\nRenamed and updated to verify the NEW (correct) behavior: _pgs_from_log_obj returns only the SG’s own port group. The mock is simplified to a single lookup.return_value since neutron_pg_drop is no longer looked up in the per-SG path. This directly validates the root cause fix — per-SG DROP logging no longer touches the global shared port group.","commit_id":"8d0b459dbd6340401020188e782914b6c68958a0"}]}
