Repository: apache/airflow

Issue:
AIP-56 - Documentation
Some documentation needs to be written to explain what is an auth manager and some guidance on how to create concrete auth managers


Discussion:
I'm interested in this item, will look into the code and do a PR. Kindly assign this one to me

Happy to. Though, I was thinking we should work on this task later in the project once most of the code will be written, it might be easier. What do you think?
Yeah sure, makes sense! will work on this, once the base code is merged. 
Amazing!

Resolving patch:
diff --git a/scripts/ci/pre_commit/pre_commit_generate_airflow_diagrams.py b/scripts/ci/pre_commit/pre_commit_generate_airflow_diagrams.py
--- a/scripts/ci/pre_commit/pre_commit_generate_airflow_diagrams.py
+++ b/scripts/ci/pre_commit/pre_commit_generate_airflow_diagrams.py
@@ -33,17 +33,22 @@
 LOCAL_DIR = Path(__file__).parent
 AIRFLOW_SOURCES_ROOT = Path(__file__).parents[3]
 DOCS_IMAGES_DIR = AIRFLOW_SOURCES_ROOT / "docs" / "apache-airflow" / "img"
+FAB_PROVIDER_DOCS_IMAGES_DIR = AIRFLOW_SOURCES_ROOT / "docs" / "apache-airflow-providers-fab" / "img"
 PYTHON_MULTIPROCESS_LOGO = AIRFLOW_SOURCES_ROOT / "images" / "diagrams" / "python_multiprocess_logo.png"
 
 BASIC_ARCHITECTURE_IMAGE_NAME = "diagram_basic_airflow_architecture"
 DAG_PROCESSOR_AIRFLOW_ARCHITECTURE_IMAGE_NAME = "diagram_dag_processor_airflow_architecture"
+AUTH_MANAGER_AIRFLOW_ARCHITECTURE_IMAGE_NAME = "diagram_auth_manager_airflow_architecture"
+FAB_AUTH_MANAGER_AIRFLOW_ARCHITECTURE_IMAGE_NAME = "diagram_fab_auth_manager_airflow_architecture"
 DIAGRAM_HASH_FILE_NAME = "diagram_hash.txt"
 
 
-def generate_basic_airflow_diagram(filename: str):
+def generate_basic_airflow_diagram():
     basic_architecture_image_file = (DOCS_IMAGES_DIR / BASIC_ARCHITECTURE_IMAGE_NAME).with_suffix(".png")
     console.print(f"[bright_blue]Generating architecture image {basic_architecture_image_file}")
-    with Diagram(name="", show=False, direction="LR", curvestyle="ortho", filename=filename):
+    with Diagram(
+        name="", show=False, direction="LR", curvestyle="ortho", filename=BASIC_ARCHITECTURE_IMAGE_NAME
+    ):
         with Cluster("Parsing & Scheduling"):
             schedulers = Custom("Scheduler(s)", PYTHON_MULTIPROCESS_LOGO.as_posix())
 
@@ -78,12 +83,18 @@ def generate_basic_airflow_diagram(filename: str):
     console.print(f"[green]Generating architecture image {basic_architecture_image_file}")
 
 
-def generate_dag_processor_airflow_diagram(filename: str):
+def generate_dag_processor_airflow_diagram():
     dag_processor_architecture_image_file = (
         DOCS_IMAGES_DIR / DAG_PROCESSOR_AIRFLOW_ARCHITECTURE_IMAGE_NAME
     ).with_suffix(".png")
     console.print(f"[bright_blue]Generating architecture image {dag_processor_architecture_image_file}")
-    with Diagram(name="", show=False, direction="LR", curvestyle="ortho", filename=filename):
+    with Diagram(
+        name="",
+        show=False,
+        direction="LR",
+        curvestyle="ortho",
+        filename=DAG_PROCESSOR_AIRFLOW_ARCHITECTURE_IMAGE_NAME,
+    ):
         operations_user = User("Operations User")
         with Cluster("No DAG Python Code Execution", graph_attr={"bgcolor": "lightgrey"}):
             with Cluster("Scheduling"):
@@ -121,6 +132,87 @@ def generate_dag_processor_airflow_diagram(filename: str):
     console.print(f"[green]Generating architecture image {dag_processor_architecture_image_file}")
 
 
+def generate_auth_manager_airflow_diagram():
+    auth_manager_architecture_image_file = (
+        DOCS_IMAGES_DIR / AUTH_MANAGER_AIRFLOW_ARCHITECTURE_IMAGE_NAME
+    ).with_suffix(".png")
+    console.print(f"[bright_blue]Generating architecture image {auth_manager_architecture_image_file}")
+    with Diagram(
+        name="",
+        show=False,
+        direction="LR",
+        curvestyle="ortho",
+        filename=AUTH_MANAGER_AIRFLOW_ARCHITECTURE_IMAGE_NAME,
+    ):
+        user = User("User")
+        with Cluster("Airflow environment"):
+            webserver = Custom("Webserver(s)", PYTHON_MULTIPROCESS_LOGO.as_posix())
+
+            with Cluster("Provider X"):
+                auth_manager = Custom("X auth manager", PYTHON_MULTIPROCESS_LOGO.as_posix())
+            with Cluster("Core Airflow"):
+                auth_manager_interface = Custom(
+                    "Auth manager\ninterface", PYTHON_MULTIPROCESS_LOGO.as_posix()
+                )
+
+        (user >> Edge(color="black", style="solid", reverse=True, label="Access to the console") >> webserver)
+
+        (
+            webserver
+            >> Edge(color="black", style="solid", reverse=True, label="Is user authorized?")
+            >> auth_manager
+        )
+
+        (
+            auth_manager
+            >> Edge(color="black", style="dotted", reverse=False, label="Inherit")
+            >> auth_manager_interface
+        )
+
+    console.print(f"[green]Generating architecture image {auth_manager_architecture_image_file}")
+
+
+def generate_fab_auth_manager_airflow_diagram():
+    auth_manager_architecture_image_file = (
+        FAB_PROVIDER_DOCS_IMAGES_DIR / FAB_AUTH_MANAGER_AIRFLOW_ARCHITECTURE_IMAGE_NAME
+    ).with_suffix(".png")
+    console.print(f"[bright_blue]Generating architecture image {auth_manager_architecture_image_file}")
+    with Diagram(
+        name="",
+        show=False,
+        direction="LR",
+        curvestyle="ortho",
+        filename=FAB_AUTH_MANAGER_AIRFLOW_ARCHITECTURE_IMAGE_NAME,
+    ):
+        user = User("User")
+        with Cluster("Airflow environment"):
+            webserver = Custom("Webserver(s)", PYTHON_MULTIPROCESS_LOGO.as_posix())
+
+            with Cluster("FAB provider"):
+                fab_auth_manager = Custom("FAB auth manager", PYTHON_MULTIPROCESS_LOGO.as_posix())
+            with Cluster("Core Airflow"):
+                auth_manager_interface = Custom(
+                    "Auth manager\ninterface", PYTHON_MULTIPROCESS_LOGO.as_posix()
+                )
+
+            db = PostgreSQL("Metadata DB")
+
+        user >> Edge(color="black", style="solid", reverse=True, label="Access to the console") >> webserver
+        (
+            webserver
+            >> Edge(color="black", style="solid", reverse=True, label="Is user authorized?")
+            >> fab_auth_manager
+        )
+        (fab_auth_manager >> Edge(color="black", style="solid", reverse=True) >> db)
+        (
+            fab_auth_manager
+            >> Edge(color="black", style="dotted", reverse=False, label="Inherit")
+            >> auth_manager_interface
+        )
+
+    console.print(f"[green]Generating architecture image {auth_manager_architecture_image_file}")
+
+
 def main():
     hash_md5 = hashlib.md5()
     hash_md5.update(Path(__file__).resolve().read_bytes())
@@ -128,8 +220,12 @@ def main():
     hash_file = LOCAL_DIR / DIAGRAM_HASH_FILE_NAME
     if not hash_file.exists() or not hash_file.read_text().strip() == str(my_file_hash).strip():
         os.chdir(DOCS_IMAGES_DIR)
-        generate_basic_airflow_diagram(BASIC_ARCHITECTURE_IMAGE_NAME)
-        generate_dag_processor_airflow_diagram(DAG_PROCESSOR_AIRFLOW_ARCHITECTURE_IMAGE_NAME)
+        generate_basic_airflow_diagram()
+        generate_dag_processor_airflow_diagram()
+        generate_auth_manager_airflow_diagram()
+        os.chdir(FAB_PROVIDER_DOCS_IMAGES_DIR)
+        generate_fab_auth_manager_airflow_diagram()
+        os.chdir(DOCS_IMAGES_DIR)
         hash_file.write_text(str(my_file_hash) + "\n")
     else:
         console.print("[bright_blue]No changes to generation script. Not regenerating the images.")


Test patch: