read args from environment variables as fallback

Use the same environment variables that are used by
proxmox-backup-client:
* PBS_REPOSITORY
* PBS_PASSWORD(|_FD|_FILE|_CMD)
* PBS_ENCRYPTION_PASSWORD(|_FD|_FILE|_CMD)

Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
This commit is contained in:
Filip Schauer 2024-12-02 13:32:55 +01:00 committed by Wolfgang Bumiller
parent 615173c7b5
commit e4e5fec1f6

View File

@ -1,4 +1,5 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::env::VarError::{NotPresent, NotUnicode};
use std::ffi::OsString; use std::ffi::OsString;
use std::fs::read_dir; use std::fs::read_dir;
use std::io::{BufRead, BufReader, Write}; use std::io::{BufRead, BufReader, Write};
@ -7,6 +8,7 @@ use std::path::PathBuf;
use anyhow::{bail, Context, Error}; use anyhow::{bail, Context, Error};
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use env_logger::Target; use env_logger::Target;
use pbs_client::tools::get_secret_from_env;
use proxmox_sys::linux::tty; use proxmox_sys::linux::tty;
use proxmox_time::epoch_i64; use proxmox_time::epoch_i64;
use regex::Regex; use regex::Regex;
@ -27,7 +29,7 @@ Arguments:
Options: Options:
--repository <auth_id@host:port:datastore> --repository <auth_id@host:port:datastore>
Repository URL Repository URL [env: PBS_REPOSITORY]
[--ns <NAMESPACE>] [--ns <NAMESPACE>]
Namespace Namespace
[--vmid <VMID>] [--vmid <VMID>]
@ -38,7 +40,7 @@ Options:
[--backup-time <EPOCH>] [--backup-time <EPOCH>]
Backup timestamp Backup timestamp
--fingerprint <FINGERPRINT> --fingerprint <FINGERPRINT>
Proxmox Backup Server Fingerprint [env: PBS_FINGERPRINT=] Proxmox Backup Server Fingerprint [env: PBS_FINGERPRINT]
--keyfile <KEYFILE> --keyfile <KEYFILE>
Key file Key file
--master-keyfile <MASTER_KEYFILE> --master-keyfile <MASTER_KEYFILE>
@ -48,9 +50,10 @@ Options:
-e, --encrypt -e, --encrypt
Encrypt the Backup Encrypt the Backup
--password-file <PASSWORD_FILE> --password-file <PASSWORD_FILE>
Password file Password file [env: PBS_PASSWORD, PBS_PASSWORD_FD, PBS_PASSWORD_FILE, PBS_PASSWORD_CMD]
--key-password-file <KEY_PASSWORD_FILE> --key-password-file <KEY_PASSWORD_FILE>
Key password file Key password file [env: PBS_ENCRYPTION_PASSWORD, PBS_ENCRYPTION_PASSWORD_FD,
PBS_ENCRYPTION_PASSWORD_FILE, PBS_ENCRYPTION_PASSWORD_CMD]
[--notes-file <NOTES_FILE>] [--notes-file <NOTES_FILE>]
File containing a comment/notes File containing a comment/notes
[--log-file <LOG_FILE>] [--log-file <LOG_FILE>]
@ -120,7 +123,7 @@ fn parse_args() -> Result<BackupVmaToPbsArgs, Error> {
std::process::exit(0); std::process::exit(0);
} }
let pbs_repository = args.value_from_str("--repository")?; let pbs_repository = args.opt_value_from_str("--repository")?;
let namespace = args.opt_value_from_str("--ns")?; let namespace = args.opt_value_from_str("--ns")?;
let vmid: Option<String> = args.opt_value_from_str("--vmid")?; let vmid: Option<String> = args.opt_value_from_str("--vmid")?;
let backup_time: Option<i64> = args.opt_value_from_str("--backup-time")?; let backup_time: Option<i64> = args.opt_value_from_str("--backup-time")?;
@ -149,10 +152,22 @@ fn parse_args() -> Result<BackupVmaToPbsArgs, Error> {
bail!("unexpected extra arguments, use '-h' for usage"); bail!("unexpected extra arguments, use '-h' for usage");
} }
let pbs_repository = match pbs_repository {
Some(v) => v,
None => match std::env::var("PBS_REPOSITORY") {
Ok(v) => v,
Err(NotPresent) => bail!("Repository not set. Use $PBS_REPOSITORY or --repository"),
Err(NotUnicode(_)) => bail!("$PBS_REPOSITORY contains invalid unicode"),
},
};
let fingerprint = match fingerprint { let fingerprint = match fingerprint {
Some(v) => v, Some(v) => v,
None => std::env::var("PBS_FINGERPRINT") None => match std::env::var("PBS_FINGERPRINT") {
.context("Fingerprint not set. Use $PBS_FINGERPRINT or --fingerprint")?, Ok(v) => v,
Err(NotPresent) => bail!("Fingerprint not set. Use $PBS_FINGERPRINT or --fingerprint"),
Err(NotUnicode(_)) => bail!("$PBS_FINGERPRINT contains invalid unicode"),
},
}; };
if forwarded_args.len() > 1 { if forwarded_args.len() > 1 {
@ -161,30 +176,27 @@ fn parse_args() -> Result<BackupVmaToPbsArgs, Error> {
let vma_file_path = forwarded_args.first(); let vma_file_path = forwarded_args.first();
let pbs_password = match password_file { let pbs_password = if let Some(password_file) = password_file {
Some(password_file) => { let mut password =
let mut password = std::fs::read_to_string(password_file).context("Could not read password file")?;
std::fs::read_to_string(password_file).context("Could not read password file")?;
if password.ends_with('\n') || password.ends_with('\r') { if password.ends_with('\n') || password.ends_with('\r') {
password.pop();
if password.ends_with('\r') {
password.pop(); password.pop();
if password.ends_with('\r') {
password.pop();
}
} }
password
} }
None => {
if vma_file_path.is_none() {
bail!(
"Please use --password-file to provide the password \
when passing the VMA file to stdin"
);
}
String::from_utf8(tty::read_password("Password: ")?)? password
} } else if let Some(password) = get_secret_from_env("PBS_PASSWORD")? {
password
} else if vma_file_path.is_none() {
bail!(
"Please use --password-file, $PBS_PASSWORD, $PBS_PASSWORD_FD, $PBS_PASSWORD_FILE, \
or $PBS_PASSWORD_CMD to provide the password when passing the VMA file to stdin"
);
} else {
String::from_utf8(tty::read_password("Password: ")?)?
}; };
let key_password = if keyfile.is_some() { let key_password = if keyfile.is_some() {
@ -199,6 +211,8 @@ fn parse_args() -> Result<BackupVmaToPbsArgs, Error> {
} }
} }
Some(key_password)
} else if let Some(key_password) = get_secret_from_env("PBS_ENCRYPTION_PASSWORD")? {
Some(key_password) Some(key_password)
} else if vma_file_path.is_none() { } else if vma_file_path.is_none() {
log::info!( log::info!(