uranusjr commented on a change in pull request #18916:
URL: https://github.com/apache/airflow/pull/18916#discussion_r727511440



##########
File path: airflow/cli/commands/role_command.py
##########
@@ -42,3 +44,43 @@ def roles_create(args):
     for role_name in args.role:
         appbuilder.sm.add_role(role_name)
     print(f"Added {len(args.role)} role(s)")
+
+
+@suppress_logs_and_warning
+def roles_export(args):
+    """
+    Exports all the rules from the data base to a file.
+    """
+    from airflow.www.security import EXISTING_ROLES
+    appbuilder = cached_app().appbuilder
+    roles = appbuilder.sm.get_all_roles()
+    exporting_roles = [role.name for role in roles if role.name not in 
EXISTING_ROLES]
+    with open(os.path.expanduser(args.export), 'w') as file:
+        file.write(json.dumps(exporting_roles, sort_keys=True, indent=4))
+        print(f"{len(exporting_roles)} roles successfully exported to 
{file.name}")

Review comment:
       ```suggestion
       filename = os.path.expanduser(args.export)
       with open(filename, 'w') as f:
           json.dumps(f, exporting_roles, sort_keys=True, indent=4)
       print(f"{len(exporting_roles)} roles successfully exported to 
{filename}")
   ```
   
   IIRC the encoding argument is needed for Python 3.6. Also the `dumps` part 
unnecessarily serialises data to memory.

##########
File path: airflow/cli/commands/role_command.py
##########
@@ -42,3 +44,43 @@ def roles_create(args):
     for role_name in args.role:
         appbuilder.sm.add_role(role_name)
     print(f"Added {len(args.role)} role(s)")
+
+
+@suppress_logs_and_warning
+def roles_export(args):
+    """
+    Exports all the rules from the data base to a file.
+    """
+    from airflow.www.security import EXISTING_ROLES
+    appbuilder = cached_app().appbuilder
+    roles = appbuilder.sm.get_all_roles()
+    exporting_roles = [role.name for role in roles if role.name not in 
EXISTING_ROLES]
+    with open(os.path.expanduser(args.export), 'w') as file:
+        file.write(json.dumps(exporting_roles, sort_keys=True, indent=4))
+        print(f"{len(exporting_roles)} roles successfully exported to 
{file.name}")
+
+
+@cli_utils.action_logging
+@suppress_logs_and_warning
+def roles_import(args):
+    """
+    Import all the roles into the db from the given json file.
+    """
+    json_file = getattr(args, 'import')
+    if not os.path.exists(json_file):
+        print(f"File '{json_file}' does not exist")
+        exit(1)
+
+    role_list = None
+    try:
+        with open(json_file, 'r') as file:
+            role_list = json.loads(file.read())
+    except ValueError as e:
+        print(f"File '{json_file}' is not a valid JSON file. Error: {e}")
+        exit(1)

Review comment:
       ```suggestion
       json_file = getattr(args, 'import')
       try:
           with open(json_file, 'r') as f:
               role_list = json.load(f)
       except FileNotFoundError:
           print(f"File '{json_file}' does not exist")
           exit(1)
       except ValueError as e:
           print(f"File '{json_file}' is not a valid JSON file. Error: {e}")
           exit(1)
   ```

##########
File path: airflow/cli/commands/role_command.py
##########
@@ -42,3 +44,43 @@ def roles_create(args):
     for role_name in args.role:
         appbuilder.sm.add_role(role_name)
     print(f"Added {len(args.role)} role(s)")
+
+
+@suppress_logs_and_warning
+def roles_export(args):
+    """
+    Exports all the rules from the data base to a file.
+    """
+    from airflow.www.security import EXISTING_ROLES
+    appbuilder = cached_app().appbuilder
+    roles = appbuilder.sm.get_all_roles()
+    exporting_roles = [role.name for role in roles if role.name not in 
EXISTING_ROLES]
+    with open(os.path.expanduser(args.export), 'w') as file:
+        file.write(json.dumps(exporting_roles, sort_keys=True, indent=4))
+        print(f"{len(exporting_roles)} roles successfully exported to 
{file.name}")
+
+
+@cli_utils.action_logging
+@suppress_logs_and_warning
+def roles_import(args):
+    """
+    Import all the roles into the db from the given json file.
+    """
+    json_file = getattr(args, 'import')
+    if not os.path.exists(json_file):
+        print(f"File '{json_file}' does not exist")
+        exit(1)
+
+    role_list = None
+    try:
+        with open(json_file, 'r') as file:
+            role_list = json.loads(file.read())
+    except ValueError as e:
+        print(f"File '{json_file}' is not a valid JSON file. Error: {e}")
+        exit(1)
+    appbuilder = cached_app().appbuilder
+    existing_roles = [role.name for role in appbuilder.sm.get_all_roles()]
+    roles_to_import = [role for role in role_list if role not in 
existing_roles]
+    for role_name in roles_to_import:
+        appbuilder.sm.add_role(role_name)

Review comment:
       I think we need to better handle existing roles. Maybe check they have 
the same permissions and error out on mismatch? Or maybe prompt? Or at least 
log a warning? Ignoring sliently doesn't feel right.

##########
File path: airflow/cli/commands/role_command.py
##########
@@ -42,3 +44,43 @@ def roles_create(args):
     for role_name in args.role:
         appbuilder.sm.add_role(role_name)
     print(f"Added {len(args.role)} role(s)")
+
+
+@suppress_logs_and_warning
+def roles_export(args):
+    """
+    Exports all the rules from the data base to a file.
+    """
+    from airflow.www.security import EXISTING_ROLES

Review comment:
       Why does this need to be imported locally?

##########
File path: airflow/cli/cli_parser.py
##########
@@ -683,6 +683,8 @@ def _check(value):
 # roles
 ARG_CREATE_ROLE = Arg(('-c', '--create'), help='Create a new role', 
action='store_true')
 ARG_LIST_ROLES = Arg(('-l', '--list'), help='List roles', action='store_true')
+ARG_ROLE_EXPORT = Arg(("--export",), metavar="FILEPATH", help="Export roles to 
JSON file")
+ARG_ROLE_IMPORT = Arg(("--import",), metavar="FILEPATH", help="Import roles 
from JSON file to db")

Review comment:
       Are these committed accidentally?

##########
File path: airflow/cli/commands/role_command.py
##########
@@ -17,6 +17,8 @@
 # under the License.
 #
 """Roles sub-commands"""
+import os
+from airflow.settings import json

Review comment:
       ```suggestion
   import json
   import os
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to