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]