tape: impl api permissions for drive/changer/pool configuration

This commit is contained in:
Dietmar Maurer 2021-03-03 12:10:00 +01:00
parent b90cb34fd6
commit 8cd63df0dc
5 changed files with 150 additions and 9 deletions

View File

@ -6,12 +6,21 @@ use proxmox::api::{
api, api,
Router, Router,
RpcEnvironment, RpcEnvironment,
Permission,
schema::parse_property_string, schema::parse_property_string,
}; };
use crate::{ use crate::{
config, config::{
self,
cached_user_info::CachedUserInfo,
acl::{
PRIV_TAPE_AUDIT,
PRIV_TAPE_MODIFY,
},
},
api2::types::{ api2::types::{
Authid,
PROXMOX_CONFIG_DIGEST_SCHEMA, PROXMOX_CONFIG_DIGEST_SCHEMA,
CHANGER_NAME_SCHEMA, CHANGER_NAME_SCHEMA,
SCSI_CHANGER_PATH_SCHEMA, SCSI_CHANGER_PATH_SCHEMA,
@ -42,6 +51,9 @@ use crate::{
}, },
}, },
}, },
access: {
permission: &Permission::Privilege(&["tape", "changer"], PRIV_TAPE_MODIFY, false),
},
)] )]
/// Create a new changer device /// Create a new changer device
pub fn create_changer( pub fn create_changer(
@ -94,7 +106,9 @@ pub fn create_changer(
returns: { returns: {
type: ScsiTapeChanger, type: ScsiTapeChanger,
}, },
access: {
permission: &Permission::Privilege(&["tape", "changer", "{name}"], PRIV_TAPE_AUDIT, false),
},
)] )]
/// Get tape changer configuration /// Get tape changer configuration
pub fn get_config( pub fn get_config(
@ -123,17 +137,31 @@ pub fn get_config(
type: ScsiTapeChanger, type: ScsiTapeChanger,
}, },
}, },
access: {
description: "List configured tape changer filtered by Tape.Audit privileges",
permission: &Permission::Anybody,
},
)] )]
/// List changers /// List changers
pub fn list_changers( pub fn list_changers(
_param: Value, _param: Value,
mut rpcenv: &mut dyn RpcEnvironment, mut rpcenv: &mut dyn RpcEnvironment,
) -> Result<Vec<ScsiTapeChanger>, Error> { ) -> Result<Vec<ScsiTapeChanger>, Error> {
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
let user_info = CachedUserInfo::new()?;
let (config, digest) = config::drive::config()?; let (config, digest) = config::drive::config()?;
let list: Vec<ScsiTapeChanger> = config.convert_to_typed_array("changer")?; let list: Vec<ScsiTapeChanger> = config.convert_to_typed_array("changer")?;
let list = list
.into_iter()
.filter(|changer| {
let privs = user_info.lookup_privs(&auth_id, &["tape", "changer", &changer.name]);
privs & PRIV_TAPE_AUDIT != 0
})
.collect();
rpcenv["digest"] = proxmox::tools::digest_to_hex(&digest).into(); rpcenv["digest"] = proxmox::tools::digest_to_hex(&digest).into();
Ok(list) Ok(list)
@ -177,6 +205,9 @@ pub enum DeletableProperty {
}, },
}, },
}, },
access: {
permission: &Permission::Privilege(&["tape", "changer", "{name}"], PRIV_TAPE_MODIFY, false),
},
)] )]
/// Update a tape changer configuration /// Update a tape changer configuration
pub fn update_changer( pub fn update_changer(
@ -251,6 +282,9 @@ pub fn update_changer(
}, },
}, },
}, },
access: {
permission: &Permission::Privilege(&["tape", "changer", "{name}"], PRIV_TAPE_MODIFY, false),
},
)] )]
/// Delete a tape changer configuration /// Delete a tape changer configuration
pub fn delete_changer(name: String, _param: Value) -> Result<(), Error> { pub fn delete_changer(name: String, _param: Value) -> Result<(), Error> {

View File

@ -2,11 +2,19 @@ use anyhow::{bail, Error};
use ::serde::{Deserialize, Serialize}; use ::serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
use proxmox::api::{api, Router, RpcEnvironment}; use proxmox::api::{api, Router, RpcEnvironment, Permission};
use crate::{ use crate::{
config, config::{
self,
cached_user_info::CachedUserInfo,
acl::{
PRIV_TAPE_AUDIT,
PRIV_TAPE_MODIFY,
},
},
api2::types::{ api2::types::{
Authid,
PROXMOX_CONFIG_DIGEST_SCHEMA, PROXMOX_CONFIG_DIGEST_SCHEMA,
DRIVE_NAME_SCHEMA, DRIVE_NAME_SCHEMA,
CHANGER_NAME_SCHEMA, CHANGER_NAME_SCHEMA,
@ -41,6 +49,9 @@ use crate::{
}, },
}, },
}, },
access: {
permission: &Permission::Privilege(&["tape", "drive"], PRIV_TAPE_MODIFY, false),
},
)] )]
/// Create a new drive /// Create a new drive
pub fn create_drive(param: Value) -> Result<(), Error> { pub fn create_drive(param: Value) -> Result<(), Error> {
@ -84,6 +95,9 @@ pub fn create_drive(param: Value) -> Result<(), Error> {
returns: { returns: {
type: LinuxTapeDrive, type: LinuxTapeDrive,
}, },
access: {
permission: &Permission::Privilege(&["tape", "drive", "{name}"], PRIV_TAPE_AUDIT, false),
},
)] )]
/// Get drive configuration /// Get drive configuration
pub fn get_config( pub fn get_config(
@ -112,17 +126,31 @@ pub fn get_config(
type: LinuxTapeDrive, type: LinuxTapeDrive,
}, },
}, },
access: {
description: "List configured tape drives filtered by Tape.Audit privileges",
permission: &Permission::Anybody,
},
)] )]
/// List drives /// List drives
pub fn list_drives( pub fn list_drives(
_param: Value, _param: Value,
mut rpcenv: &mut dyn RpcEnvironment, mut rpcenv: &mut dyn RpcEnvironment,
) -> Result<Vec<LinuxTapeDrive>, Error> { ) -> Result<Vec<LinuxTapeDrive>, Error> {
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
let user_info = CachedUserInfo::new()?;
let (config, digest) = config::drive::config()?; let (config, digest) = config::drive::config()?;
let drive_list: Vec<LinuxTapeDrive> = config.convert_to_typed_array("linux")?; let drive_list: Vec<LinuxTapeDrive> = config.convert_to_typed_array("linux")?;
let drive_list = drive_list
.into_iter()
.filter(|drive| {
let privs = user_info.lookup_privs(&auth_id, &["tape", "drive", &drive.name]);
privs & PRIV_TAPE_AUDIT != 0
})
.collect();
rpcenv["digest"] = proxmox::tools::digest_to_hex(&digest).into(); rpcenv["digest"] = proxmox::tools::digest_to_hex(&digest).into();
Ok(drive_list) Ok(drive_list)
@ -173,6 +201,9 @@ pub enum DeletableProperty {
}, },
}, },
}, },
access: {
permission: &Permission::Privilege(&["tape", "drive", "{name}"], PRIV_TAPE_MODIFY, false),
},
)] )]
/// Update a drive configuration /// Update a drive configuration
pub fn update_drive( pub fn update_drive(
@ -246,6 +277,9 @@ pub fn update_drive(
}, },
}, },
}, },
access: {
permission: &Permission::Privilege(&["tape", "drive", "{name}"], PRIV_TAPE_MODIFY, false),
},
)] )]
/// Delete a drive configuration /// Delete a drive configuration
pub fn delete_drive(name: String, _param: Value) -> Result<(), Error> { pub fn delete_drive(name: String, _param: Value) -> Result<(), Error> {

View File

@ -6,11 +6,13 @@ use proxmox::{
api, api,
Router, Router,
RpcEnvironment, RpcEnvironment,
Permission,
}, },
}; };
use crate::{ use crate::{
api2::types::{ api2::types::{
Authid,
MEDIA_POOL_NAME_SCHEMA, MEDIA_POOL_NAME_SCHEMA,
MEDIA_SET_NAMING_TEMPLATE_SCHEMA, MEDIA_SET_NAMING_TEMPLATE_SCHEMA,
MEDIA_SET_ALLOCATION_POLICY_SCHEMA, MEDIA_SET_ALLOCATION_POLICY_SCHEMA,
@ -19,7 +21,14 @@ use crate::{
SINGLE_LINE_COMMENT_SCHEMA, SINGLE_LINE_COMMENT_SCHEMA,
MediaPoolConfig, MediaPoolConfig,
}, },
config, config::{
self,
cached_user_info::CachedUserInfo,
acl::{
PRIV_TAPE_AUDIT,
PRIV_TAPE_MODIFY,
},
},
}; };
#[api( #[api(
@ -32,6 +41,9 @@ use crate::{
}, },
}, },
}, },
access: {
permission: &Permission::Privilege(&["tape", "pool"], PRIV_TAPE_MODIFY, false),
},
)] )]
/// Create a new media pool /// Create a new media pool
pub fn create_pool( pub fn create_pool(
@ -61,15 +73,29 @@ pub fn create_pool(
type: MediaPoolConfig, type: MediaPoolConfig,
}, },
}, },
access: {
description: "List configured media pools filtered by Tape.Audit privileges",
permission: &Permission::Anybody,
},
)] )]
/// List media pools /// List media pools
pub fn list_pools( pub fn list_pools(
mut rpcenv: &mut dyn RpcEnvironment, mut rpcenv: &mut dyn RpcEnvironment,
) -> Result<Vec<MediaPoolConfig>, Error> { ) -> Result<Vec<MediaPoolConfig>, Error> {
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
let user_info = CachedUserInfo::new()?;
let (config, digest) = config::media_pool::config()?; let (config, digest) = config::media_pool::config()?;
let list = config.convert_to_typed_array("pool")?; let list = config.convert_to_typed_array::<MediaPoolConfig>("pool")?;
let list = list
.into_iter()
.filter(|pool| {
let privs = user_info.lookup_privs(&auth_id, &["tape", "pool", &pool.name]);
privs & PRIV_TAPE_AUDIT != 0
})
.collect();
rpcenv["digest"] = proxmox::tools::digest_to_hex(&digest).into(); rpcenv["digest"] = proxmox::tools::digest_to_hex(&digest).into();
@ -87,6 +113,9 @@ pub fn list_pools(
returns: { returns: {
type: MediaPoolConfig, type: MediaPoolConfig,
}, },
access: {
permission: &Permission::Privilege(&["tape", "pool", "{name}"], PRIV_TAPE_AUDIT, false),
},
)] )]
/// Get media pool configuration /// Get media pool configuration
pub fn get_config(name: String) -> Result<MediaPoolConfig, Error> { pub fn get_config(name: String) -> Result<MediaPoolConfig, Error> {
@ -152,6 +181,9 @@ pub enum DeletableProperty {
}, },
}, },
}, },
access: {
permission: &Permission::Privilege(&["tape", "pool", "{name}"], PRIV_TAPE_MODIFY, false),
},
)] )]
/// Update media pool settings /// Update media pool settings
pub fn update_pool( pub fn update_pool(
@ -212,6 +244,9 @@ pub fn update_pool(
}, },
}, },
}, },
access: {
permission: &Permission::Privilege(&["tape", "pool", "{name}"], PRIV_TAPE_MODIFY, false),
},
)] )]
/// Delete a media pool configuration /// Delete a media pool configuration
pub fn delete_pool(name: String) -> Result<(), Error> { pub fn delete_pool(name: String) -> Result<(), Error> {

View File

@ -4,12 +4,19 @@ use std::path::Path;
use anyhow::Error; use anyhow::Error;
use serde_json::Value; use serde_json::Value;
use proxmox::api::{api, Router, SubdirMap}; use proxmox::api::{api, Router, SubdirMap, RpcEnvironment, Permission};
use proxmox::list_subdirs_api_method; use proxmox::list_subdirs_api_method;
use crate::{ use crate::{
config, config::{
self,
cached_user_info::CachedUserInfo,
acl::{
PRIV_TAPE_AUDIT,
},
},
api2::types::{ api2::types::{
Authid,
CHANGER_NAME_SCHEMA, CHANGER_NAME_SCHEMA,
ChangerListEntry, ChangerListEntry,
LinuxTapeDrive, LinuxTapeDrive,
@ -178,11 +185,18 @@ pub async fn transfer(
type: ChangerListEntry, type: ChangerListEntry,
}, },
}, },
access: {
description: "List configured tape changer filtered by Tape.Audit privileges",
permission: &Permission::Anybody,
},
)] )]
/// List changers /// List changers
pub fn list_changers( pub fn list_changers(
_param: Value, _param: Value,
rpcenv: &mut dyn RpcEnvironment,
) -> Result<Vec<ChangerListEntry>, Error> { ) -> Result<Vec<ChangerListEntry>, Error> {
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
let user_info = CachedUserInfo::new()?;
let (config, _digest) = config::drive::config()?; let (config, _digest) = config::drive::config()?;
@ -193,6 +207,11 @@ pub fn list_changers(
let mut list = Vec::new(); let mut list = Vec::new();
for changer in changer_list { for changer in changer_list {
let privs = user_info.lookup_privs(&auth_id, &["tape", "changer", &changer.name]);
if (privs & PRIV_TAPE_AUDIT) == 0 {
continue;
}
let info = lookup_device_identification(&linux_changers, &changer.path); let info = lookup_device_identification(&linux_changers, &changer.path);
let entry = ChangerListEntry { config: changer, info }; let entry = ChangerListEntry { config: changer, info };
list.push(entry); list.push(entry);

View File

@ -16,6 +16,7 @@ use proxmox::{
section_config::SectionConfigData, section_config::SectionConfigData,
RpcEnvironment, RpcEnvironment,
RpcEnvironmentType, RpcEnvironmentType,
Permission,
Router, Router,
SubdirMap, SubdirMap,
}, },
@ -23,7 +24,13 @@ use proxmox::{
use crate::{ use crate::{
task_log, task_log,
config, config::{
self,
cached_user_info::CachedUserInfo,
acl::{
PRIV_TAPE_AUDIT,
},
},
api2::{ api2::{
types::{ types::{
UPID_SCHEMA, UPID_SCHEMA,
@ -1203,12 +1210,19 @@ pub fn catalog_media(
type: DriveListEntry, type: DriveListEntry,
}, },
}, },
access: {
description: "List configured tape drives filtered by Tape.Audit privileges",
permission: &Permission::Anybody,
},
)] )]
/// List drives /// List drives
pub fn list_drives( pub fn list_drives(
changer: Option<String>, changer: Option<String>,
_param: Value, _param: Value,
rpcenv: &mut dyn RpcEnvironment,
) -> Result<Vec<DriveListEntry>, Error> { ) -> Result<Vec<DriveListEntry>, Error> {
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
let user_info = CachedUserInfo::new()?;
let (config, _) = config::drive::config()?; let (config, _) = config::drive::config()?;
@ -1223,6 +1237,11 @@ pub fn list_drives(
continue; continue;
} }
let privs = user_info.lookup_privs(&auth_id, &["tape", "drive", &drive.name]);
if (privs & PRIV_TAPE_AUDIT) == 0 {
continue;
}
let info = lookup_device_identification(&linux_drives, &drive.path); let info = lookup_device_identification(&linux_drives, &drive.path);
let state = get_tape_device_state(&config, &drive.name)?; let state = get_tape_device_state(&config, &drive.name)?;
let entry = DriveListEntry { config: drive, info, state }; let entry = DriveListEntry { config: drive, info, state };