tape: add hardware encryption key managenent api

This commit is contained in:
Dietmar Maurer
2021-01-18 07:16:06 +01:00
parent 4e9cc3e97c
commit d5a48b5ce4
15 changed files with 518 additions and 37 deletions

View File

@ -952,6 +952,7 @@ fn main() {
.insert("drive", drive_commands())
.insert("pool", pool_commands())
.insert("media", media_commands())
.insert("key", encryption_key_commands())
.insert(
"load-media",
CliCommand::new(&API_METHOD_LOAD_MEDIA)

View File

@ -0,0 +1,70 @@
use anyhow::Error;
use serde_json::Value;
use proxmox::{
api::{
api,
cli::*,
RpcEnvironment,
ApiHandler,
},
};
use proxmox_backup::{
api2::{
self,
},
config::tape_encryption_keys::complete_key_fingerprint,
};
pub fn encryption_key_commands() -> CommandLineInterface {
let cmd_def = CliCommandMap::new()
.insert("list", CliCommand::new(&API_METHOD_LIST_KEYS))
.insert(
"create",
CliCommand::new(&api2::config::tape_encryption_keys::API_METHOD_CREATE_KEY)
)
.insert(
"remove",
CliCommand::new(&api2::config::tape_encryption_keys::API_METHOD_DELETE_KEY)
.arg_param(&["fingerprint"])
.completion_cb("fingerprint", complete_key_fingerprint)
)
;
cmd_def.into()
}
#[api(
input: {
properties: {
"output-format": {
schema: OUTPUT_FORMAT,
optional: true,
},
},
},
)]
/// List keys
fn list_keys(
param: Value,
rpcenv: &mut dyn RpcEnvironment,
) -> Result<(), Error> {
let output_format = get_output_format(&param);
let info = &api2::config::tape_encryption_keys::API_METHOD_LIST_KEYS;
let mut data = match info.handler {
ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?,
_ => unreachable!(),
};
let options = default_table_format_options()
.column(ColumnConfig::new("fingerprint"))
.column(ColumnConfig::new("hint"))
;
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
Ok(())
}

View File

@ -9,3 +9,6 @@ pub use pool::*;
mod media;
pub use media::*;
mod encryption_key;
pub use encryption_key::*;

View File

@ -21,9 +21,11 @@ use proxmox::{
use proxmox_backup::{
config,
backup::Fingerprint,
api2::types::{
LINUX_DRIVE_PATH_SCHEMA,
DRIVE_NAME_SCHEMA,
TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
LinuxTapeDrive,
},
tape::{
@ -42,8 +44,7 @@ fn get_tape_handle(param: &Value) -> Result<LinuxTapeHandle, Error> {
let (config, _digest) = config::drive::config()?;
let drive: LinuxTapeDrive = config.lookup("linux", &name)?;
eprintln!("using device {}", drive.path);
drive.open()
.map_err(|err| format_err!("open drive '{}' ({}) failed - {}", name, drive.path, err))?
drive.open()?
} else if let Some(device) = param["device"].as_str() {
eprintln!("using device {}", device);
LinuxTapeHandle::new(open_linux_tape_device(&device)?)
@ -57,8 +58,7 @@ fn get_tape_handle(param: &Value) -> Result<LinuxTapeHandle, Error> {
let (config, _digest) = config::drive::config()?;
let drive: LinuxTapeDrive = config.lookup("linux", &name)?;
eprintln!("using device {}", drive.path);
drive.open()
.map_err(|err| format_err!("open drive '{}' ({}) failed - {}", name, drive.path, err))?
drive.open()?
} else {
let (config, _digest) = config::drive::config()?;
@ -72,8 +72,7 @@ fn get_tape_handle(param: &Value) -> Result<LinuxTapeHandle, Error> {
let name = drive_names[0];
let drive: LinuxTapeDrive = config.lookup("linux", &name)?;
eprintln!("using device {}", drive.path);
drive.open()
.map_err(|err| format_err!("open drive '{}' ({}) failed - {}", name, drive.path, err))?
drive.open()?
} else {
bail!("no drive/device specified");
}
@ -187,6 +186,47 @@ fn tape_alert_flags(
Ok(())
}
#[api(
input: {
properties: {
fingerprint: {
schema: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
optional: true,
},
drive: {
schema: DRIVE_NAME_SCHEMA,
optional: true,
},
device: {
schema: LINUX_DRIVE_PATH_SCHEMA,
optional: true,
},
stdin: {
description: "Use standard input as device handle.",
type: bool,
optional: true,
},
},
},
)]
/// Set or clear encryption key
fn set_encryption(
fingerprint: Option<Fingerprint>,
param: Value,
) -> Result<(), Error> {
let result = proxmox::try_block!({
let mut handle = get_tape_handle(&param)?;
handle.set_encryption(fingerprint)?;
Ok(())
}).map_err(|err: Error| err.to_string());
println!("{}", serde_json::to_string_pretty(&result)?);
Ok(())
}
#[api(
input: {
properties: {
@ -260,6 +300,10 @@ fn main() -> Result<(), Error> {
"volume-statistics",
CliCommand::new(&API_METHOD_VOLUME_STATISTICS)
)
.insert(
"encryption",
CliCommand::new(&API_METHOD_SET_ENCRYPTION)
)
;
let mut rpcenv = CliEnvironment::new();