This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new d8f8270a39d Keep sync-perm going when a Dag has bad access_control 
(#71798)
d8f8270a39d is described below

commit d8f8270a39d7b563eb847a3b40014b32122fe5be
Author: Mayank Joshi <[email protected]>
AuthorDate: Wed Sep 23 04:00:44 2026 +0530

    Keep sync-perm going when a Dag has bad access_control (#71798)
    
    * Keep sync-perm going when a Dag has bad access_control
    
    A single Dag whose access_control references a non-existent role (or an
    invalid resource/action) made airflow sync-perm --include-dags abort
    partway through, leaving every remaining Dag without its permissions
    synced. Skip the misconfigured Dag and continue with the rest so one bad
    Dag can no longer block permission sync for all good ones.
    
    * Fix test isolation in sync-perm bad access_control test
    
    Address review feedback on #71798: restore test_get_all_permissions as its
    own function (its body had been merged into the new test's tail), and use
    "Dag" in the skip log message per the repo prose convention.
---
 .../fab/auth_manager/security_manager/override.py  |  9 ++++++++-
 .../tests/unit/fab/auth_manager/test_security.py   | 23 ++++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git 
a/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py
 
b/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py
index bd1c9c6ab14..1d5ac262714 100644
--- 
a/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py
+++ 
b/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py
@@ -1036,7 +1036,14 @@ class 
FabAirflowSecurityManagerOverride(AirflowSecurityManagerV2):
                         self._merge_perm(action_name, dag_resource_name)
 
             if dag.access_control is not None:
-                self.sync_perm_for_dag(dag.dag_id, dag.access_control)
+                try:
+                    self.sync_perm_for_dag(dag.dag_id, dag.access_control)
+                except FabException:
+                    self.log.exception(
+                        "Failed to sync permissions for Dag '%s'; skipping it 
and continuing with "
+                        "the remaining Dags. Fix its access_control 
configuration and re-run sync-perm.",
+                        dag.dag_id,
+                    )
 
     def sync_perm_for_dag(
         self,
diff --git a/providers/fab/tests/unit/fab/auth_manager/test_security.py 
b/providers/fab/tests/unit/fab/auth_manager/test_security.py
index 18d855ce61a..c73b94b9669 100644
--- a/providers/fab/tests/unit/fab/auth_manager/test_security.py
+++ b/providers/fab/tests/unit/fab/auth_manager/test_security.py
@@ -1109,6 +1109,29 @@ def 
test_create_dag_specific_permissions_airflow3(session, security_manager, mon
         security_manager.create_dag_specific_permissions()
 
 
+def 
test_create_dag_specific_permissions_skips_dag_with_bad_access_control(security_manager,
 monkeypatch):
+    """A single DAG with an invalid access_control must not abort syncing the 
remaining DAGs."""
+    bad_dag = DAG("bad_access_control", schedule=None, 
access_control={"NonExistentRole": {ACTION_CAN_READ}})
+    good_dag = DAG("good_access_control", schedule=None, 
access_control={"Public": {ACTION_CAN_READ}})
+
+    import airflow.providers.fab.auth_manager.security_manager
+
+    _iter_dags_mock = mock.Mock(return_value=[bad_dag, good_dag])
+    monkeypatch.setitem(
+        airflow.providers.fab.auth_manager.security_manager.override.__dict__, 
"_iter_dags", _iter_dags_mock
+    )
+
+    try:
+        security_manager.create_dag_specific_permissions()
+
+        good_perms = security_manager.get_all_permissions()
+        good_resource_name = _resource_name(good_dag.dag_id, 
permissions.RESOURCE_DAG)
+        assert (ACTION_CAN_READ, good_resource_name) in good_perms
+    finally:
+        _delete_dag_permissions(bad_dag.dag_id, security_manager)
+        _delete_dag_permissions(good_dag.dag_id, security_manager)
+
+
 def test_get_all_permissions(security_manager):
     with assert_queries_count(1):
         perms = security_manager.get_all_permissions()

Reply via email to