]> git.proxmox.com Git - proxmox-backup.git/commitdiff
use proxmox 0.1.25, use new EnumEntry feature
authorDietmar Maurer <dietmar@proxmox.com>
Wed, 29 Apr 2020 11:01:24 +0000 (13:01 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Wed, 29 Apr 2020 11:01:24 +0000 (13:01 +0200)
Cargo.toml
src/api2/access/acl.rs
src/api2/access/role.rs
src/api2/reader.rs
src/api2/types.rs
src/bin/proxmox-backup-client.rs
src/config/acl.rs
tests/verify-api.rs

index 3fc633012c70f8c1881b4691104a14925794eed8..2df47e9b0bf11a931e432dc3c5b3b23831e5ec9b 100644 (file)
@@ -34,7 +34,7 @@ pam = "0.7"
 pam-sys = "0.5"
 percent-encoding = "2.1"
 pin-utils = "0.1.0-alpha"
-proxmox = { version = "0.1.24", features = [ "sortable-macro", "api-macro" ] }
+proxmox = { version = "0.1.25", features = [ "sortable-macro", "api-macro" ] }
 #proxmox = { git = "ssh://gitolite3@proxdev.maurer-it.com/rust/proxmox", version = "0.1.2", features = [ "sortable-macro", "api-macro" ] }
 #proxmox = { path = "../proxmox/proxmox", features = [ "sortable-macro", "api-macro" ] }
 regex = "1.2"
index d18b39763279be13f683b5d1a713d97d5e46950a..92d4a31e9beb256819e85970cf6ae29336f75f4f 100644 (file)
@@ -5,7 +5,7 @@ use proxmox::api::{api, Router, RpcEnvironment, Permission};
 
 use crate::api2::types::*;
 use crate::config::acl;
-use crate::config::acl::{PRIV_SYS_AUDIT, PRIV_SYS_MODIFY};
+use crate::config::acl::{Role, PRIV_SYS_AUDIT, PRIV_SYS_MODIFY};
 
 #[api(
     properties: {
@@ -23,7 +23,7 @@ use crate::config::acl::{PRIV_SYS_AUDIT, PRIV_SYS_MODIFY};
             description: "User or Group ID.",
         },
        roleid: {
-            schema: ACL_ROLE_SCHEMA,
+            type: Role,
         }
     }
 )]
@@ -118,7 +118,7 @@ pub fn read_acl(
                 schema: ACL_PATH_SCHEMA,
             },
            role: {
-                schema: ACL_ROLE_SCHEMA,
+                type: Role,
             },
             propagate: {
                 optional: true,
index bdf51fa3ef54e61fecaccdb70239dbc7b3630880..3d284dea0a8decc28490ce6af766f129782f5a7c 100644 (file)
@@ -6,7 +6,7 @@ use proxmox::api::{api, Permission};
 use proxmox::api::router::Router;
 
 use crate::api2::types::*;
-use crate::config::acl::ROLE_NAMES;
+use crate::config::acl::{Role, ROLE_NAMES};
 
 #[api(
     returns: {
@@ -17,7 +17,7 @@ use crate::config::acl::ROLE_NAMES;
             description: "User name with description.",
             properties: {
                 role: {
-                    schema: ACL_ROLE_SCHEMA,
+                    type: Role,
                 },
                 comment: {
                     schema: SINGLE_LINE_COMMENT_SCHEMA,
index 88206bd9199a402935a65711311eaba45d0da970..cb0001535ef1c447b83179c8d7d33869ef03bb00 100644 (file)
@@ -31,15 +31,9 @@ pub const API_METHOD_UPGRADE_BACKUP: ApiMethod = ApiMethod::new(
         concat!("Upgraded to backup protocol ('", PROXMOX_BACKUP_READER_PROTOCOL_ID_V1!(), "')."),
         &sorted!([
             ("store", false, &DATASTORE_SCHEMA),
-            ("backup-type", false, &StringSchema::new("Backup type.")
-             .format(&ApiStringFormat::Enum(&["vm", "ct", "host"]))
-             .schema()
-            ),
-            ("backup-id", false, &StringSchema::new("Backup ID.").schema()),
-            ("backup-time", false, &IntegerSchema::new("Backup time (Unix epoch.)")
-             .minimum(1_547_797_308)
-             .schema()
-            ),
+            ("backup-type", false, &BACKUP_TYPE_SCHEMA),
+            ("backup-id", false, &BACKUP_ID_SCHEMA),
+            ("backup-time", false, &BACKUP_TIME_SCHEMA),
             ("debug", true, &BooleanSchema::new("Enable verbose debug logging.").schema()),
         ]),
     )
index 5a0b355df8b503afa6b26ea35c4ba47ffee147df..f5c32d9db9bd90349efb24b5923efed24fbb6967 100644 (file)
@@ -248,24 +248,9 @@ pub const ACL_PROPAGATE_SCHEMA: Schema = BooleanSchema::new(
 
 pub const ACL_UGID_TYPE_SCHEMA: Schema = StringSchema::new(
     "Type of 'ugid' property.")
-    .format(&ApiStringFormat::Enum(&["user", "group"]))
-    .schema();
-
-pub const ACL_ROLE_SCHEMA: Schema = StringSchema::new(
-    "Role.")
     .format(&ApiStringFormat::Enum(&[
-        "Admin",
-        "Audit",
-        "Datastore.Admin",
-        "Datastore.Reader",
-        "Datastore.Audit",
-        "Datastore.Backup",
-        "Datastore.PowerUser",
-        "Remote.Admin",
-        "Remote.Audit",
-        "Remote.SyncOperator",
-        "NoAccess",
-    ]))
+        EnumEntry::new("user", "User"),
+        EnumEntry::new("group", "Group")]))
     .schema();
 
 pub const BACKUP_ARCHIVE_NAME_SCHEMA: Schema =
@@ -275,7 +260,10 @@ pub const BACKUP_ARCHIVE_NAME_SCHEMA: Schema =
 
 pub const BACKUP_TYPE_SCHEMA: Schema =
     StringSchema::new("Backup type.")
-    .format(&ApiStringFormat::Enum(&["vm", "ct", "host"]))
+    .format(&ApiStringFormat::Enum(&[
+        EnumEntry::new("vm", "Virtual Machine Backup"),
+        EnumEntry::new("ct", "Container Backup"),
+        EnumEntry::new("host", "Host Backup")]))
     .schema();
 
 pub const BACKUP_ID_SCHEMA: Schema =
index b54cd729c046f8a239b5fa1bb7cd06f7ce78372e..474a0ca5160a54d6a76453017cb03ccd7112b851 100644 (file)
@@ -1852,7 +1852,9 @@ fn key_mgmt_cli() -> CliCommandMap {
 
     const KDF_SCHEMA: Schema =
         StringSchema::new("Key derivation function. Choose 'none' to store the key unecrypted.")
-        .format(&ApiStringFormat::Enum(&["scrypt", "none"]))
+        .format(&ApiStringFormat::Enum(&[
+            EnumEntry::new("scrypt", "SCrypt"),
+            EnumEntry::new("none", "Do not encrypt the key")]))
         .default("scrypt")
         .schema();
 
index 7a3b314a21f71ded4b1b8bd810651e4c813149fd..c8734265b8c4afa7b801a606cf28ca2b4428af61 100644 (file)
@@ -2,12 +2,17 @@ use std::io::Write;
 use std::collections::{HashMap, HashSet, BTreeMap, BTreeSet};
 use std::path::{PathBuf, Path};
 use std::sync::{Arc, RwLock};
+use std::str::FromStr;
 
 use anyhow::{bail, Error};
 
 use lazy_static::lazy_static;
 
+use ::serde::{Deserialize, Serialize};
+use serde::de::{value, IntoDeserializer};
+
 use proxmox::tools::{fs::replace_file, fs::CreateOptions};
+use proxmox::api::{api, schema::*};
 
 // define Privilege bitfield
 
@@ -83,56 +88,56 @@ PRIV_REMOTE_PRUNE;
 
 pub const ROLE_NAME_NO_ACCESS: &str ="NoAccess";
 
+#[api()]
+#[repr(u64)]
+#[derive(Serialize, Deserialize)]
+/// Role
+pub enum Role {
+    /// Administrator
+    Admin = ROLE_ADMIN,
+    /// Auditor
+    Audit = ROLE_AUDIT,
+    /// Disable Access
+    NoAccess = ROLE_NO_ACCESS,
+    /// Datastore Administrator
+    DatastoreAdmin = ROLE_DATASTORE_ADMIN,
+    /// Datastore Reader (inspect datastore content and do restores)
+    DatastoreReader = ROLE_DATASTORE_READER,
+    /// Datastore Backup (backup and restore owned backups)
+    DatastoreBackup = ROLE_DATASTORE_BACKUP,
+    /// Datastore PowerUser (backup, restore and prune owned backup)
+    DatastorePowerUser = ROLE_DATASTORE_POWERUSER,
+    /// Datastore Auditor
+    DatastoreAudit = ROLE_DATASTORE_AUDIT,
+    /// Remote Auditor
+    RemoteAudit = ROLE_REMOTE_AUDIT,
+    /// Remote Administrator
+    RemoteAdmin = ROLE_REMOTE_ADMIN,
+    /// Syncronisation Opertator
+    RemoteSyncOperator = ROLE_REMOTE_SYNC_OPERATOR,
+}
+
+impl FromStr for Role {
+    type Err = value::Error;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        Self::deserialize(s.into_deserializer())
+    }
+}
+
 lazy_static! {
     pub static ref ROLE_NAMES: HashMap<&'static str, (u64, &'static str)> = {
         let mut map = HashMap::new();
 
-        map.insert("Admin", (
-            ROLE_ADMIN,
-            "Administrator",
-        ));
-        map.insert("Audit", (
-            ROLE_AUDIT,
-            "Auditor",
-        ));
-        map.insert(ROLE_NAME_NO_ACCESS, (
-            ROLE_NO_ACCESS,
-            "Disable access",
-        ));
-
-        map.insert("Datastore.Admin", (
-            ROLE_DATASTORE_ADMIN,
-            "Datastore Administrator",
-        ));
-        map.insert("Datastore.Reader", (
-            ROLE_DATASTORE_READER,
-            "Datastore Reader (inspect datastore content and do restores)",
-        ));
-        map.insert("Datastore.Backup", (
-            ROLE_DATASTORE_BACKUP,
-            "Datastore Backup (backup and restore owned backups)",
-        ));
-        map.insert("Datastore.PowerUser", (
-            ROLE_DATASTORE_POWERUSER,
-            "Datastore PowerUser (backup, restore and prune owned backup)",
-        ));
-        map.insert("Datastore.Audit", (
-            ROLE_DATASTORE_AUDIT,
-            "Datastore Auditor",
-        ));
-
-        map.insert("Remote.Audit", (
-            ROLE_REMOTE_AUDIT,
-            "Remote Auditor",
-        ));
-        map.insert("Remote.Admin", (
-            ROLE_REMOTE_ADMIN,
-            "Remote Administrator",
-        ));
-        map.insert("Remote.SyncOperator", (
-            ROLE_REMOTE_SYNC_OPERATOR,
-            "Syncronisation Opertator",
-        ));
+        let list = match Role::API_SCHEMA {
+            Schema::String(StringSchema { format: Some(ApiStringFormat::Enum(list)), .. }) => list,
+            _ => unreachable!(),
+        };
+
+        for entry in list.iter() {
+            let privs: u64 = Role::from_str(entry.value).unwrap() as u64;
+            map.insert(entry.value, (privs, entry.description));
+        }
 
         map
     };
@@ -615,15 +620,15 @@ mod test {
         let tree = AclTree::from_raw(r###"
 acl:0:/store/store2:user1:Admin
 acl:0:/store/store2:user2:Admin
-acl:0:/store/store2:user1:Datastore.Backup
-acl:0:/store/store2:user2:Datastore.Backup
+acl:0:/store/store2:user1:DatastoreBackup
+acl:0:/store/store2:user2:DatastoreBackup
 "###)?;
 
         let mut raw: Vec<u8> = Vec::new();
         tree.write_config(&mut raw)?;
         let raw = std::str::from_utf8(&raw)?;
 
-        assert_eq!(raw, "acl:0:/store/store2:user1,user2:Admin,Datastore.Backup\n");
+        assert_eq!(raw, "acl:0:/store/store2:user1,user2:Admin,DatastoreBackup\n");
 
         Ok(())
     }
@@ -633,18 +638,18 @@ acl:0:/store/store2:user2:Datastore.Backup
 
         let tree = AclTree::from_raw(r###"
 acl:1:/storage:user1@pbs:Admin
-acl:1:/storage/store1:user1@pbs:Datastore.Backup
-acl:1:/storage/store2:user2@pbs:Datastore.Backup
+acl:1:/storage/store1:user1@pbs:DatastoreBackup
+acl:1:/storage/store2:user2@pbs:DatastoreBackup
 "###)?;
         check_roles(&tree, "user1@pbs", "/", "");
         check_roles(&tree, "user1@pbs", "/storage", "Admin");
-        check_roles(&tree, "user1@pbs", "/storage/store1", "Datastore.Backup");
+        check_roles(&tree, "user1@pbs", "/storage/store1", "DatastoreBackup");
         check_roles(&tree, "user1@pbs", "/storage/store2", "Admin");
 
         check_roles(&tree, "user2@pbs", "/", "");
         check_roles(&tree, "user2@pbs", "/storage", "");
         check_roles(&tree, "user2@pbs", "/storage/store1", "");
-        check_roles(&tree, "user2@pbs", "/storage/store2", "Datastore.Backup");
+        check_roles(&tree, "user2@pbs", "/storage/store2", "DatastoreBackup");
 
         Ok(())
     }
@@ -655,22 +660,22 @@ acl:1:/storage/store2:user2@pbs:Datastore.Backup
         let tree = AclTree::from_raw(r###"
 acl:1:/:user1@pbs:Admin
 acl:1:/storage:user1@pbs:NoAccess
-acl:1:/storage/store1:user1@pbs:Datastore.Backup
+acl:1:/storage/store1:user1@pbs:DatastoreBackup
 "###)?;
         check_roles(&tree, "user1@pbs", "/", "Admin");
         check_roles(&tree, "user1@pbs", "/storage", "NoAccess");
-        check_roles(&tree, "user1@pbs", "/storage/store1", "Datastore.Backup");
+        check_roles(&tree, "user1@pbs", "/storage/store1", "DatastoreBackup");
         check_roles(&tree, "user1@pbs", "/storage/store2", "NoAccess");
         check_roles(&tree, "user1@pbs", "/system", "Admin");
 
         let tree = AclTree::from_raw(r###"
 acl:1:/:user1@pbs:Admin
 acl:0:/storage:user1@pbs:NoAccess
-acl:1:/storage/store1:user1@pbs:Datastore.Backup
+acl:1:/storage/store1:user1@pbs:DatastoreBackup
 "###)?;
         check_roles(&tree, "user1@pbs", "/", "Admin");
         check_roles(&tree, "user1@pbs", "/storage", "NoAccess");
-        check_roles(&tree, "user1@pbs", "/storage/store1", "Datastore.Backup");
+        check_roles(&tree, "user1@pbs", "/storage/store1", "DatastoreBackup");
         check_roles(&tree, "user1@pbs", "/storage/store2", "Admin");
         check_roles(&tree, "user1@pbs", "/system", "Admin");
 
index a5887758ecaa82edde800fa0103056892ab5715b..d919f1547dd0a342c33297463ad6fa5ad10f3ac0 100644 (file)
@@ -142,27 +142,3 @@ fn verify_root_api() -> Result<(), Error> {
 
     Ok(())
 }
-
-#[test]
-fn verify_acl_role_schema() -> Result<(), Error> {
-
-    let list = match api2::types::ACL_ROLE_SCHEMA {
-        Schema::String(StringSchema { format: Some(ApiStringFormat::Enum(list)), .. }) => list,
-        _ => unreachable!(),
-    };
-
-    let map = &proxmox_backup::config::acl::ROLE_NAMES;
-    for item in *list {
-        if !map.contains_key(item) {
-            bail!("found role '{}' without description/mapping", item);
-        }
-    }
-
-    for role in map.keys() {
-        if !list.contains(role) {
-            bail!("role '{}' missing in ACL_ROLE_SCHEMA enum", role);
-        }
-    }
-
-    Ok(())
-}