mirror of
https://github.com/netinvent/npbackup.git
synced 2025-10-29 14:57:15 +08:00
CLI: Refactor --repo-name and --repo-group usage
This commit is contained in:
parent
26b21dc806
commit
622dedd12c
1 changed files with 123 additions and 96 deletions
|
|
@ -75,7 +75,7 @@ This is free software, and you are welcome to redistribute it under certain cond
|
||||||
type=str,
|
type=str,
|
||||||
default=None,
|
default=None,
|
||||||
required=False,
|
required=False,
|
||||||
help="Name of the repository to work with. Defaults to 'default'. In group operation mode, this can be a comma separated list of repo names. Can accept special name '__all__' to work with all repositories.",
|
help="Name of the repository to work with. Defaults to 'default'. This can also be a comma separated list of repo names. Can accept special name '__all__' to work with all repositories.",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--repo-group",
|
"--repo-group",
|
||||||
|
|
@ -279,7 +279,7 @@ This is free software, and you are welcome to redistribute it under certain cond
|
||||||
type=str,
|
type=str,
|
||||||
default=None,
|
default=None,
|
||||||
required=False,
|
required=False,
|
||||||
help="Launch an operation on a group of repositories given by --repo-group or --repo-name. Valid group operations are [backup|restore|snapshots|list|ls|find|policy|quick_check|full_check|prune|prune_max|unlock|repair_index|repair_packs|repair_snapshots|recover|dump|stats|raw|has_recent_snapshot]",
|
help="Deprecated command to launch operations on multiple repositories. Not needed anymore",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--create-key",
|
"--create-key",
|
||||||
|
|
@ -381,49 +381,36 @@ This is free software, and you are welcome to redistribute it under certain cond
|
||||||
json_error_logging(True, "Config file seems valid", "info")
|
json_error_logging(True, "Config file seems valid", "info")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
if args.create_backup_scheduled_task or args.create_housekeeping_scheduled_task:
|
repos = []
|
||||||
try:
|
repos_and_group_repos = []
|
||||||
if "interval" in args.create_scheduled_task:
|
if not args.repo_name and not args.repo_group:
|
||||||
interval = args.create_scheduled_task.split("=")[1].strip()
|
repos_and_group_repos.append("default")
|
||||||
result = create_scheduled_task(
|
if args.repo_name:
|
||||||
config_file, type="backup", interval_minutes=int(interval)
|
if args.repo_name == "__all__":
|
||||||
)
|
repos += npbackup.configuration.get_repo_list(full_config)
|
||||||
elif (
|
else:
|
||||||
"hour" in args.create_scheduled_task
|
repos += [repo.strip() for repo in args.repo_name.split(",")]
|
||||||
and "minute" in args.create_scheduled_task
|
# Let's keep _repos list for later "repo only" usage
|
||||||
):
|
repos_and_group_repos += repos
|
||||||
if args.create_backup_scheduled_task:
|
if args.repo_group:
|
||||||
type = "backup"
|
groups = [group.strip() for group in args.repo_group.split(",")]
|
||||||
if args.create_housekeeping_scheduled_task:
|
for group in groups:
|
||||||
type = "housekeeping"
|
repos_and_group_repos += npbackup.configuration.get_repos_by_group(
|
||||||
hours, minutes = args.create_scheduled_task.split(",")
|
full_config, group
|
||||||
hour = hours.split("=")[1].strip()
|
)
|
||||||
minute = minutes.split("=")[1].strip()
|
if repos_and_group_repos == []:
|
||||||
result = create_scheduled_task(
|
json_error_logging(
|
||||||
config_file, type=type, hour=int(hour), minute=int(minute)
|
False,
|
||||||
)
|
f"No corresponding repo found for --repo-group setting {args.repo_group}",
|
||||||
if not result:
|
level="error",
|
||||||
msg = "Scheduled task creation failed"
|
)
|
||||||
json_error_logging(False, msg, "critical")
|
sys.exit(74)
|
||||||
sys.exit(72)
|
|
||||||
else:
|
|
||||||
msg = "Scheduled task created successfully"
|
|
||||||
json_error_logging(True, msg, "info")
|
|
||||||
sys.exit(0)
|
|
||||||
else:
|
|
||||||
msg = "Invalid interval or hour and minute given for scheduled task"
|
|
||||||
json_error_logging(False, msg, "critical")
|
|
||||||
except (TypeError, ValueError, IndexError) as exc:
|
|
||||||
logger.debug("Trace:", exc_info=True)
|
|
||||||
msg = f"Bogus data given for scheduled task: {exc}"
|
|
||||||
json_error_logging(False, msg, "critical")
|
|
||||||
sys.exit(72)
|
|
||||||
|
|
||||||
if not args.group_operation:
|
# Single repo usage
|
||||||
repo_name = args.repo_name
|
if len(repos_and_group_repos) == 1:
|
||||||
if repo_name is None:
|
repo_config, _ = npbackup.configuration.get_repo_config(
|
||||||
repo_name = "default"
|
full_config, repos_and_group_repos[0]
|
||||||
repo_config, _ = npbackup.configuration.get_repo_config(full_config, repo_name)
|
)
|
||||||
if not repo_config:
|
if not repo_config:
|
||||||
msg = "Cannot find repo config"
|
msg = "Cannot find repo config"
|
||||||
json_error_logging(False, msg, "critical")
|
json_error_logging(False, msg, "critical")
|
||||||
|
|
@ -440,26 +427,82 @@ This is free software, and you are welcome to redistribute it under certain cond
|
||||||
sys.exit(73)
|
sys.exit(73)
|
||||||
|
|
||||||
if args.show_config:
|
if args.show_config:
|
||||||
# NPF-SEC-00009
|
repos_config = []
|
||||||
# Load an anonymous version of the repo config
|
for repo in repos_and_group_repos:
|
||||||
show_encrypted = False
|
repo_config, _ = npbackup.configuration.get_repo_config(full_config, repo)
|
||||||
session_manager_password = os.environ.get("NPBACKUP_MANAGER_PASSWORD", None)
|
if not repo_config:
|
||||||
if session_manager_password:
|
logger.error(f"Missing config for repository {repo}")
|
||||||
manager_password = repo_config.g("manager_password")
|
else:
|
||||||
if manager_password:
|
# NPF-SEC-00009
|
||||||
if manager_password == session_manager_password:
|
# Load an anonymous version of the repo config
|
||||||
show_encrypted = True
|
show_encrypted = False
|
||||||
else:
|
session_manager_password = os.environ.get(
|
||||||
# NPF-SEC
|
"NPBACKUP_MANAGER_PASSWORD", None
|
||||||
sleep(2) # Sleep to avoid brute force attacks
|
)
|
||||||
logger.error("Wrong manager password")
|
if session_manager_password:
|
||||||
sys.exit(74)
|
manager_password = repo_config.g("manager_password")
|
||||||
repo_config = npbackup.configuration.get_anonymous_repo_config(
|
if manager_password:
|
||||||
repo_config, show_encrypted=show_encrypted
|
if manager_password == session_manager_password:
|
||||||
)
|
show_encrypted = True
|
||||||
print(json.dumps(repo_config, indent=4))
|
else:
|
||||||
|
# NPF-SEC
|
||||||
|
sleep(2) # Sleep to avoid brute force attacks
|
||||||
|
logger.error("Wrong manager password")
|
||||||
|
sys.exit(74)
|
||||||
|
repo_config = npbackup.configuration.get_anonymous_repo_config(
|
||||||
|
repo_config, show_encrypted=show_encrypted
|
||||||
|
)
|
||||||
|
repos_config.append(repo_config)
|
||||||
|
print(json.dumps(repos_config, indent=4))
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
if args.create_backup_scheduled_task or args.create_housekeeping_scheduled_task:
|
||||||
|
|
||||||
|
def _create_task(repo=None, group=None):
|
||||||
|
try:
|
||||||
|
if "interval" in args.create_scheduled_task:
|
||||||
|
interval = args.create_scheduled_task.split("=")[1].strip()
|
||||||
|
result = create_scheduled_task(
|
||||||
|
config_file, type="backup", interval_minutes=int(interval)
|
||||||
|
)
|
||||||
|
elif (
|
||||||
|
"hour" in args.create_scheduled_task
|
||||||
|
and "minute" in args.create_scheduled_task
|
||||||
|
):
|
||||||
|
if args.create_backup_scheduled_task:
|
||||||
|
type = "backup"
|
||||||
|
if args.create_housekeeping_scheduled_task:
|
||||||
|
type = "housekeeping"
|
||||||
|
hours, minutes = args.create_scheduled_task.split(",")
|
||||||
|
hour = hours.split("=")[1].strip()
|
||||||
|
minute = minutes.split("=")[1].strip()
|
||||||
|
result = create_scheduled_task(
|
||||||
|
config_file, type=type, hour=int(hour), minute=int(minute)
|
||||||
|
)
|
||||||
|
if not result:
|
||||||
|
msg = "Scheduled task creation failed"
|
||||||
|
json_error_logging(False, msg, "critical")
|
||||||
|
sys.exit(72)
|
||||||
|
else:
|
||||||
|
msg = "Scheduled task created successfully"
|
||||||
|
json_error_logging(True, msg, "info")
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
msg = "Invalid interval or hour and minute given for scheduled task"
|
||||||
|
json_error_logging(False, msg, "critical")
|
||||||
|
except (TypeError, ValueError, IndexError) as exc:
|
||||||
|
logger.debug("Trace:", exc_info=True)
|
||||||
|
msg = f"Bogus data given for scheduled task: {exc}"
|
||||||
|
json_error_logging(False, msg, "critical")
|
||||||
|
sys.exit(72)
|
||||||
|
|
||||||
|
if groups:
|
||||||
|
for group in groups:
|
||||||
|
_create_task(repo=None, group=group)
|
||||||
|
if repos:
|
||||||
|
for repo in repos:
|
||||||
|
_create_task(repo=repo, group=None)
|
||||||
|
|
||||||
# Try to perform an auto upgrade if needed
|
# Try to perform an auto upgrade if needed
|
||||||
try:
|
try:
|
||||||
auto_upgrade = full_config["global_options"]["auto_upgrade"]
|
auto_upgrade = full_config["global_options"]["auto_upgrade"]
|
||||||
|
|
@ -495,7 +538,6 @@ This is free software, and you are welcome to redistribute it under certain cond
|
||||||
|
|
||||||
# Prepare program run
|
# Prepare program run
|
||||||
cli_args = {
|
cli_args = {
|
||||||
"repo_config": repo_config,
|
|
||||||
"verbose": args.verbose,
|
"verbose": args.verbose,
|
||||||
"dry_run": args.dry_run,
|
"dry_run": args.dry_run,
|
||||||
"json_output": args.json,
|
"json_output": args.json,
|
||||||
|
|
@ -505,6 +547,10 @@ This is free software, and you are welcome to redistribute it under certain cond
|
||||||
"op_args": {},
|
"op_args": {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Single repo run
|
||||||
|
if len(repos_and_group_repos) == 1:
|
||||||
|
cli_args["repo_config"] = (repo_config,)
|
||||||
|
|
||||||
# On group operations, we also need to set op_args
|
# On group operations, we also need to set op_args
|
||||||
|
|
||||||
if args.stdin:
|
if args.stdin:
|
||||||
|
|
@ -591,8 +637,8 @@ This is free software, and you are welcome to redistribute it under certain cond
|
||||||
elif args.init:
|
elif args.init:
|
||||||
cli_args["operation"] = "init"
|
cli_args["operation"] = "init"
|
||||||
|
|
||||||
# Group operation mode
|
#### Group operation mode
|
||||||
if args.group_operation and args.group_operation not in (
|
possible_group_ops = (
|
||||||
"backup",
|
"backup",
|
||||||
"restore",
|
"restore",
|
||||||
"snapshots",
|
"snapshots",
|
||||||
|
|
@ -614,37 +660,16 @@ This is free software, and you are welcome to redistribute it under certain cond
|
||||||
"stats",
|
"stats",
|
||||||
"raw",
|
"raw",
|
||||||
"has_recent_snapshot",
|
"has_recent_snapshot",
|
||||||
):
|
)
|
||||||
logger.critical(
|
if len(repos_and_group_repos) > 1:
|
||||||
f"Invalid group operation {args.group_operation}. Valid operations are [backup|restore|snapshots|list|ls|find|policy|housekeeping|quick_check|full_check|prune|prune_max|unlock|repair_index|repair_packs|repair_snapshots|recover|dump|stats|raw|has_recent_snapshot]"
|
if cli_args["operation"] not in possible_group_ops:
|
||||||
)
|
logger.critical(
|
||||||
sys.exit(74)
|
f"Invalid group operation {cli_args['operation']}. Valid operations are {','.join(possible_group_ops)}"
|
||||||
repo_config_list = []
|
|
||||||
repos = []
|
|
||||||
if args.group_operation:
|
|
||||||
if args.repo_group:
|
|
||||||
groups = [group.strip() for group in args.repo_group.split(",")]
|
|
||||||
for group in groups:
|
|
||||||
repos = npbackup.configuration.get_repos_by_group(full_config, group)
|
|
||||||
if repos is None or repos == []:
|
|
||||||
json_error_logging(
|
|
||||||
False, "No corresponding repo found", level="error"
|
|
||||||
)
|
|
||||||
sys.exit(74)
|
|
||||||
elif args.repo_name:
|
|
||||||
if args.repo_name == "__all__":
|
|
||||||
repos = npbackup.configuration.get_repo_list(full_config)
|
|
||||||
else:
|
|
||||||
repos = [repo.strip() for repo in args.repo_name.split(",")]
|
|
||||||
else:
|
|
||||||
json_error_logging(
|
|
||||||
False,
|
|
||||||
"No repository names or groups have been provided for group operation. Please use --repo-group or --repo-name",
|
|
||||||
level="critical",
|
|
||||||
)
|
)
|
||||||
sys.exit(74)
|
sys.exit(74)
|
||||||
|
repo_config_list = []
|
||||||
|
|
||||||
for repo in repos:
|
for repo in repos_and_group_repos:
|
||||||
repo_config, _ = npbackup.configuration.get_repo_config(full_config, repo)
|
repo_config, _ = npbackup.configuration.get_repo_config(full_config, repo)
|
||||||
if repo_config is None:
|
if repo_config is None:
|
||||||
json_error_logging(
|
json_error_logging(
|
||||||
|
|
@ -652,14 +677,16 @@ This is free software, and you are welcome to redistribute it under certain cond
|
||||||
f"Repo {repo} does not exist in this configuration",
|
f"Repo {repo} does not exist in this configuration",
|
||||||
level="error",
|
level="error",
|
||||||
)
|
)
|
||||||
repos.remove(repo)
|
repos_and_group_repos.remove(repo)
|
||||||
else:
|
else:
|
||||||
repo_config_list.append(repo_config)
|
repo_config_list.append(repo_config)
|
||||||
|
|
||||||
if repos is None or repos == []:
|
if repos_and_group_repos is None or repos_and_group_repos == []:
|
||||||
json_error_logging(False, "No valid repos selected", level="error")
|
json_error_logging(False, "No valid repos selected", level="error")
|
||||||
sys.exit(74)
|
sys.exit(74)
|
||||||
logger.info(f"Running group operations for repos: {', '.join(repos)}")
|
logger.info(
|
||||||
|
f"Found repositories {', '.join(repos_and_group_repos)} corresponding to groups {', '.join(groups)}"
|
||||||
|
)
|
||||||
|
|
||||||
op = cli_args["operation"]
|
op = cli_args["operation"]
|
||||||
cli_args["operation"] = "group_runner"
|
cli_args["operation"] = "group_runner"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue