use anyhow::{bail, Error};
use serde_json::Value;
-use proxmox::{
- api::{
- api,
- cli::*,
- RpcEnvironment,
- ApiHandler,
- },
- sys::linux::tty,
-};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
+use proxmox::sys::linux::tty;
-use proxmox_backup::{
- tools,
- config,
- api2::{
- self,
- types::{
- DRIVE_NAME_SCHEMA,
- TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
- PASSWORD_HINT_SCHEMA,
- Kdf,
- },
- },
- config::tape_encryption_keys::complete_key_fingerprint,
+use pbs_api_types::{
+ Fingerprint, Kdf, DRIVE_NAME_SCHEMA, TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
+ PASSWORD_HINT_SCHEMA,
};
+use pbs_datastore::paperkey::{PaperkeyFormat, generate_paper_key};
+use pbs_config::tape_encryption_keys::{load_key_configs,complete_key_fingerprint};
+
+use proxmox_backup::api2;
+
pub fn encryption_key_commands() -> CommandLineInterface {
let cmd_def = CliCommandMap::new()
.arg_param(&["fingerprint"])
.completion_cb("fingerprint", complete_key_fingerprint)
)
+ .insert(
+ "paperkey",
+ CliCommand::new(&API_METHOD_PAPER_KEY)
+ .arg_param(&["fingerprint"])
+ .completion_cb("fingerprint", complete_key_fingerprint)
+ )
.insert(
"restore",
CliCommand::new(&API_METHOD_RESTORE_KEY)
cmd_def.into()
}
+#[api(
+ input: {
+ properties: {
+ fingerprint: {
+ schema: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
+ },
+ subject: {
+ description: "Include the specified subject as title text.",
+ optional: true,
+ },
+ "output-format": {
+ type: PaperkeyFormat,
+ optional: true,
+ },
+ },
+ },
+)]
+/// Generate a printable, human readable text file containing the encryption key.
+///
+/// This also includes a scanable QR code for fast key restore.
+fn paper_key(
+ fingerprint: Fingerprint,
+ subject: Option<String>,
+ output_format: Option<PaperkeyFormat>,
+) -> Result<(), Error> {
+
+ let (config_map, _digest) = load_key_configs()?;
+
+ let key_config = match config_map.get(&fingerprint) {
+ Some(key_config) => key_config,
+ None => bail!("tape encryption key '{}' does not exist.", fingerprint),
+ };
+
+ let data: String = serde_json::to_string_pretty(&key_config)?;
+
+ generate_paper_key(std::io::stdout(), &data, subject, output_format)
+}
+
#[api(
input: {
properties: {
},
},
)]
-/// Print tthe encryption key's metadata.
+/// Print the encryption key's metadata.
fn show_key(
param: Value,
rpcenv: &mut dyn RpcEnvironment,
_ => unreachable!(),
};
- let options = proxmox::api::cli::default_table_format_options()
+ let options = proxmox_router::cli::default_table_format_options()
.column(ColumnConfig::new("kdf"))
- .column(ColumnConfig::new("created").renderer(tools::format::render_epoch))
- .column(ColumnConfig::new("modified").renderer(tools::format::render_epoch))
+ .column(ColumnConfig::new("created").renderer(pbs_tools::format::render_epoch))
+ .column(ColumnConfig::new("modified").renderer(pbs_tools::format::render_epoch))
.column(ColumnConfig::new("fingerprint"))
.column(ColumnConfig::new("hint"));
rpcenv: &mut dyn RpcEnvironment,
) -> Result<(), Error> {
- let (config, _digest) = config::drive::config()?;
- param["drive"] = crate::lookup_drive_name(¶m, &config)?.into();
+ let (config, _digest) = pbs_config::drive::config()?;
+ param["drive"] = crate::extract_drive_name(&mut param, &config)?.into();
if !tty::stdin_isatty() {
bail!("no password input mechanism available");