]> git.proxmox.com Git - proxmox-backup.git/blobdiff - src/api2/config/media_pool.rs
update to first proxmox crate split
[proxmox-backup.git] / src / api2 / config / media_pool.rs
index 33e4993eeff9598e00e83c77a435a5f3c5082701..6f72ac420994ac9a5a61e6968e08700b9dbcb4ea 100644 (file)
@@ -1,94 +1,46 @@
 use anyhow::{bail, Error};
 use ::serde::{Deserialize, Serialize};
 
-use proxmox::{
-    api::{
-        api,
-        Router,
-        RpcEnvironment,
-    },
-};
+use proxmox_router::{Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
 
-use crate::{
-    api2::types::{
-        DRIVE_NAME_SCHEMA,
-        MEDIA_POOL_NAME_SCHEMA,
-        MEDIA_SET_NAMING_TEMPLATE_SCHEMA,
-        MEDIA_SET_ALLOCATION_POLICY_SCHEMA,
-        MEDIA_RETENTION_POLICY_SCHEMA,
-        TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
-        MediaPoolConfig,
-    },
-    config::{
-        self,
-        drive::{
-            check_drive_exists,
-        },
-    },
+use pbs_api_types::{
+    Authid, MediaPoolConfig, MediaPoolConfigUpdater, MEDIA_POOL_NAME_SCHEMA,
+    PRIV_TAPE_AUDIT, PRIV_TAPE_MODIFY,
 };
 
+use pbs_config::CachedUserInfo;
+
 #[api(
     protected: true,
     input: {
         properties: {
-            name: {
-                schema: MEDIA_POOL_NAME_SCHEMA,
-            },
-            drive: {
-                schema: DRIVE_NAME_SCHEMA,
-            },
-            allocation: {
-                schema: MEDIA_SET_ALLOCATION_POLICY_SCHEMA,
-                optional: true,
-            },
-            retention: {
-                schema: MEDIA_RETENTION_POLICY_SCHEMA,
-                optional: true,
-            },
-            template: {
-                schema: MEDIA_SET_NAMING_TEMPLATE_SCHEMA,
-                optional: true,
-            },
-            encrypt: {
-                schema: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
-                optional: true,
+            config: {
+                type: MediaPoolConfig,
+                flatten: true,
             },
         },
     },
+    access: {
+        permission: &Permission::Privilege(&["tape", "pool"], PRIV_TAPE_MODIFY, false),
+    },
 )]
 /// Create a new media pool
 pub fn create_pool(
-    name: String,
-    drive: String,
-    allocation: Option<String>,
-    retention: Option<String>,
-    template: Option<String>,
-    encrypt: Option<String>,
+    config: MediaPoolConfig,
 ) -> Result<(), Error> {
 
-    let _lock = config::media_pool::lock()?;
+    let _lock = pbs_config::media_pool::lock()?;
 
-    let (mut config, _digest) = config::media_pool::config()?;
+    let (mut section_config, _digest) = pbs_config::media_pool::config()?;
 
-    if config.sections.get(&name).is_some() {
-        bail!("Media pool '{}' already exists", name);
+    if section_config.sections.get(&config.name).is_some() {
+        bail!("Media pool '{}' already exists", config.name);
     }
 
-    let (drive_config, _) = config::drive::config()?;
-    check_drive_exists(&drive_config, &drive)?;
+    section_config.set_data(&config.name, "pool", &config)?;
 
-    let item = MediaPoolConfig {
-        name: name.clone(),
-        drive,
-        allocation,
-        retention,
-        template,
-        encrypt,
-    };
-
-    config.set_data(&name, "pool", &item)?;
-
-    config::media_pool::save_config(&config)?;
+    pbs_config::media_pool::save_config(&section_config)?;
 
     Ok(())
 }
@@ -101,15 +53,29 @@ pub fn create_pool(
             type: MediaPoolConfig,
         },
     },
+    access: {
+        description: "List configured media pools filtered by Tape.Audit privileges",
+        permission: &Permission::Anybody,
+    },
 )]
 /// List media pools
 pub fn list_pools(
     mut rpcenv: &mut dyn RpcEnvironment,
 ) -> 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) = pbs_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();
 
@@ -127,11 +93,14 @@ pub fn list_pools(
     returns: {
         type: MediaPoolConfig,
     },
+    access: {
+        permission: &Permission::Privilege(&["tape", "pool", "{name}"], PRIV_TAPE_AUDIT, false),
+    },
 )]
 /// Get media pool configuration
 pub fn get_config(name: String) -> Result<MediaPoolConfig, Error> {
 
-    let (config, _digest) = config::media_pool::config()?;
+    let (config, _digest) = pbs_config::media_pool::config()?;
 
     let data: MediaPoolConfig = config.lookup("pool", &name)?;
 
@@ -151,6 +120,8 @@ pub enum DeletableProperty {
     template,
     /// Delete encryption fingerprint
     encrypt,
+    /// Delete comment
+    comment,
 }
 
 #[api(
@@ -160,25 +131,9 @@ pub enum DeletableProperty {
             name: {
                 schema: MEDIA_POOL_NAME_SCHEMA,
             },
-            drive: {
-                schema: DRIVE_NAME_SCHEMA,
-                optional: true,
-            },
-            allocation: {
-                schema: MEDIA_SET_ALLOCATION_POLICY_SCHEMA,
-                optional: true,
-            },
-            retention: {
-                schema: MEDIA_RETENTION_POLICY_SCHEMA,
-                optional: true,
-            },
-            template: {
-                schema: MEDIA_SET_NAMING_TEMPLATE_SCHEMA,
-                optional: true,
-            },
-            encrypt: {
-                schema: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
-                optional: true,
+            update: {
+                type: MediaPoolConfigUpdater,
+                flatten: true,
             },
             delete: {
                 description: "List of properties to delete.",
@@ -190,21 +145,20 @@ pub enum DeletableProperty {
             },
        },
     },
+    access: {
+        permission: &Permission::Privilege(&["tape", "pool", "{name}"], PRIV_TAPE_MODIFY, false),
+    },
 )]
 /// Update media pool settings
 pub fn update_pool(
     name: String,
-    drive: Option<String>,
-    allocation: Option<String>,
-    retention: Option<String>,
-    template: Option<String>,
-    encrypt: Option<String>,
+    update: MediaPoolConfigUpdater,
     delete: Option<Vec<DeletableProperty>>,
 ) -> Result<(), Error> {
 
-    let _lock = config::media_pool::lock()?;
+    let _lock = pbs_config::media_pool::lock()?;
 
-    let (mut config, _digest) = config::media_pool::config()?;
+    let (mut config, _digest) = pbs_config::media_pool::config()?;
 
     let mut data: MediaPoolConfig = config.lookup("pool", &name)?;
 
@@ -215,19 +169,28 @@ pub fn update_pool(
                 DeletableProperty::retention => { data.retention = None; },
                 DeletableProperty::template => { data.template = None; },
                 DeletableProperty::encrypt => { data.encrypt = None; },
+                DeletableProperty::comment => { data.comment = None; },
             }
         }
     }
 
-    if let Some(drive) = drive { data.drive = drive; }
-    if allocation.is_some() { data.allocation = allocation; }
-    if retention.is_some() { data.retention = retention; }
-    if template.is_some() { data.template = template; }
-    if encrypt.is_some() { data.encrypt = encrypt; }
+    if update.allocation.is_some() { data.allocation = update.allocation; }
+    if update.retention.is_some() { data.retention = update.retention; }
+    if update.template.is_some() { data.template = update.template; }
+    if update.encrypt.is_some() { data.encrypt = update.encrypt; }
+
+    if let Some(comment) = update.comment {
+        let comment = comment.trim();
+        if comment.is_empty() {
+            data.comment = None;
+        } else {
+            data.comment = Some(comment.to_string());
+        }
+    }
 
     config.set_data(&name, "pool", &data)?;
 
-    config::media_pool::save_config(&config)?;
+    pbs_config::media_pool::save_config(&config)?;
 
     Ok(())
 }
@@ -241,20 +204,23 @@ pub fn update_pool(
             },
         },
     },
+    access: {
+        permission: &Permission::Privilege(&["tape", "pool", "{name}"], PRIV_TAPE_MODIFY, false),
+    },
 )]
 /// Delete a media pool configuration
 pub fn delete_pool(name: String) -> Result<(), Error> {
 
-    let _lock = config::media_pool::lock()?;
+    let _lock = pbs_config::media_pool::lock()?;
 
-    let (mut config, _digest) = config::media_pool::config()?;
+    let (mut config, _digest) = pbs_config::media_pool::config()?;
 
     match config.sections.get(&name) {
         Some(_) => { config.sections.remove(&name); },
         None => bail!("delete pool '{}' failed - no such pool", name),
     }
 
-    config::media_pool::save_config(&config)?;
+    pbs_config::media_pool::save_config(&config)?;
 
     Ok(())
 }