[pbs-devel] [PATCH proxmox-backup] pbs-api-types: use const_format and new api-types from proxmox-schema
Dietmar Maurer
dietmar at proxmox.com
Wed Mar 20 11:03:55 CET 2024
Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
---
Cargo.toml | 2 +
pbs-api-types/Cargo.toml | 1 +
pbs-api-types/src/acl.rs | 5 +-
pbs-api-types/src/common_regex.rs | 78 ---------
pbs-api-types/src/datastore.rs | 29 ++--
pbs-api-types/src/jobs.rs | 11 +-
pbs-api-types/src/lib.rs | 274 +++++++-----------------------
pbs-api-types/src/tape/mod.rs | 8 +-
pbs-config/src/network/helper.rs | 7 -
pbs-config/src/network/parser.rs | 2 +-
src/api2/node/dns.rs | 6 +-
11 files changed, 105 insertions(+), 318 deletions(-)
delete mode 100644 pbs-api-types/src/common_regex.rs
diff --git a/Cargo.toml b/Cargo.toml
index 00dc4d86..676d76ad 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -108,6 +108,7 @@ bitflags = "1.2.1"
bytes = "1.0"
cidr = "0.2.1"
crc32fast = "1"
+const_format = "0.2"
crossbeam-channel = "0.5"
endian_trait = { version = "0.6", features = ["arrays"] }
env_logger = "0.10"
@@ -158,6 +159,7 @@ base64.workspace = true
bitflags.workspace = true
bytes.workspace = true
cidr.workspace = true
+const_format.workspace = true
crc32fast.workspace = true
crossbeam-channel.workspace = true
endian_trait.workspace = true
diff --git a/pbs-api-types/Cargo.toml b/pbs-api-types/Cargo.toml
index 31b69f62..94ab583b 100644
--- a/pbs-api-types/Cargo.toml
+++ b/pbs-api-types/Cargo.toml
@@ -7,6 +7,7 @@ description = "general API type helpers for PBS"
[dependencies]
anyhow.workspace = true
+const_format.workspace = true
hex.workspace = true
lazy_static.workspace = true
percent-encoding.workspace = true
diff --git a/pbs-api-types/src/acl.rs b/pbs-api-types/src/acl.rs
index 8bbd2958..b2583b6a 100644
--- a/pbs-api-types/src/acl.rs
+++ b/pbs-api-types/src/acl.rs
@@ -2,14 +2,17 @@ use std::str::FromStr;
use serde::de::{value, IntoDeserializer};
use serde::{Deserialize, Serialize};
+use const_format::concatcp;
use proxmox_lang::constnamedbitmap;
use proxmox_schema::{
api, const_regex, ApiStringFormat, BooleanSchema, EnumEntry, Schema, StringSchema,
};
+use crate::PROXMOX_SAFE_ID_REGEX_STR;
+
const_regex! {
- pub ACL_PATH_REGEX = concat!(r"^(?:/|", r"(?:/", PROXMOX_SAFE_ID_REGEX_STR!(), ")+", r")$");
+ pub ACL_PATH_REGEX = concatcp!(r"^(?:/|", r"(?:/", PROXMOX_SAFE_ID_REGEX_STR, ")+", r")$");
}
// define Privilege bitfield
diff --git a/pbs-api-types/src/common_regex.rs b/pbs-api-types/src/common_regex.rs
deleted file mode 100644
index 8fe30673..00000000
--- a/pbs-api-types/src/common_regex.rs
+++ /dev/null
@@ -1,78 +0,0 @@
-//! Predefined Regular Expressions
-//!
-//! This is a collection of useful regular expressions
-
-use lazy_static::lazy_static;
-use regex::Regex;
-
-#[rustfmt::skip]
-#[macro_export]
-macro_rules! IPV4OCTET { () => (r"(?:25[0-5]|(?:2[0-4]|1[0-9]|[1-9])?[0-9])") }
-#[rustfmt::skip]
-#[macro_export]
-macro_rules! IPV6H16 { () => (r"(?:[0-9a-fA-F]{1,4})") }
-#[rustfmt::skip]
-#[macro_export]
-macro_rules! IPV6LS32 { () => (concat!(r"(?:(?:", IPV4RE!(), "|", IPV6H16!(), ":", IPV6H16!(), "))" )) }
-
-/// Returns the regular expression string to match IPv4 addresses
-#[rustfmt::skip]
-#[macro_export]
-macro_rules! IPV4RE { () => (concat!(r"(?:(?:", IPV4OCTET!(), r"\.){3}", IPV4OCTET!(), ")")) }
-
-/// Returns the regular expression string to match IPv6 addresses
-#[rustfmt::skip]
-#[macro_export]
-macro_rules! IPV6RE { () => (concat!(r"(?:",
- r"(?:(?:", r"(?:", IPV6H16!(), r":){6})", IPV6LS32!(), r")|",
- r"(?:(?:", r"::(?:", IPV6H16!(), r":){5})", IPV6LS32!(), r")|",
- r"(?:(?:(?:", IPV6H16!(), r")?::(?:", IPV6H16!(), r":){4})", IPV6LS32!(), r")|",
- r"(?:(?:(?:(?:", IPV6H16!(), r":){0,1}", IPV6H16!(), r")?::(?:", IPV6H16!(), r":){3})", IPV6LS32!(), r")|",
- r"(?:(?:(?:(?:", IPV6H16!(), r":){0,2}", IPV6H16!(), r")?::(?:", IPV6H16!(), r":){2})", IPV6LS32!(), r")|",
- r"(?:(?:(?:(?:", IPV6H16!(), r":){0,3}", IPV6H16!(), r")?::(?:", IPV6H16!(), r":){1})", IPV6LS32!(), r")|",
- r"(?:(?:(?:(?:", IPV6H16!(), r":){0,4}", IPV6H16!(), r")?::", ")", IPV6LS32!(), r")|",
- r"(?:(?:(?:(?:", IPV6H16!(), r":){0,5}", IPV6H16!(), r")?::", ")", IPV6H16!(), r")|",
- r"(?:(?:(?:(?:", IPV6H16!(), r":){0,6}", IPV6H16!(), r")?::", ")))"))
-}
-
-/// Returns the regular expression string to match IP addresses (v4 or v6)
-#[rustfmt::skip]
-#[macro_export]
-macro_rules! IPRE { () => (concat!(r"(?:", IPV4RE!(), "|", IPV6RE!(), ")")) }
-
-/// Regular expression string to match IP addresses where IPv6 addresses require brackets around
-/// them, while for IPv4 they are forbidden.
-#[rustfmt::skip]
-#[macro_export]
-macro_rules! IPRE_BRACKET { () => (
- concat!(r"(?:",
- IPV4RE!(),
- r"|\[(?:",
- IPV6RE!(),
- r")\]",
- r")"))
-}
-
-lazy_static! {
- pub static ref IP_REGEX: Regex = Regex::new(concat!(r"^", IPRE!(), r"$")).unwrap();
- pub static ref IP_BRACKET_REGEX: Regex =
- Regex::new(concat!(r"^", IPRE_BRACKET!(), r"$")).unwrap();
- pub static ref SHA256_HEX_REGEX: Regex = Regex::new(r"^[a-f0-9]{64}$").unwrap();
- pub static ref SYSTEMD_DATETIME_REGEX: Regex =
- Regex::new(r"^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}(:\d{2})?)?$").unwrap();
-}
-
-#[test]
-fn test_regexes() {
- assert!(IP_REGEX.is_match("127.0.0.1"));
- assert!(IP_REGEX.is_match("::1"));
- assert!(IP_REGEX.is_match("2014:b3a::27"));
- assert!(IP_REGEX.is_match("2014:b3a::192.168.0.1"));
- assert!(IP_REGEX.is_match("2014:b3a:0102:adf1:1234:4321:4afA:BCDF"));
-
- assert!(IP_BRACKET_REGEX.is_match("127.0.0.1"));
- assert!(IP_BRACKET_REGEX.is_match("[::1]"));
- assert!(IP_BRACKET_REGEX.is_match("[2014:b3a::27]"));
- assert!(IP_BRACKET_REGEX.is_match("[2014:b3a::192.168.0.1]"));
- assert!(IP_BRACKET_REGEX.is_match("[2014:b3a:0102:adf1:1234:4321:4afA:BCDF]"));
-}
diff --git a/pbs-api-types/src/datastore.rs b/pbs-api-types/src/datastore.rs
index cce9888b..5e13c157 100644
--- a/pbs-api-types/src/datastore.rs
+++ b/pbs-api-types/src/datastore.rs
@@ -2,6 +2,7 @@ use std::fmt;
use std::path::PathBuf;
use anyhow::{bail, format_err, Error};
+use const_format::concatcp;
use serde::{Deserialize, Serialize};
use proxmox_schema::{
@@ -10,31 +11,33 @@ use proxmox_schema::{
};
use crate::{
- Authid, CryptMode, Fingerprint, GroupFilter, MaintenanceMode, Userid,
- DATASTORE_NOTIFY_STRING_SCHEMA, GC_SCHEDULE_SCHEMA, PROXMOX_SAFE_ID_FORMAT,
- PRUNE_SCHEDULE_SCHEMA, SHA256_HEX_REGEX, SINGLE_LINE_COMMENT_SCHEMA, UPID,
+ Authid, CryptMode, Fingerprint, GroupFilter, MaintenanceMode, Userid, BACKUP_ID_RE,
+ BACKUP_NS_RE, BACKUP_TIME_RE, BACKUP_TYPE_RE, DATASTORE_NOTIFY_STRING_SCHEMA,
+ GC_SCHEDULE_SCHEMA, GROUP_OR_SNAPSHOT_PATH_REGEX_STR, PROXMOX_SAFE_ID_FORMAT,
+ PROXMOX_SAFE_ID_REGEX_STR, PRUNE_SCHEDULE_SCHEMA, SHA256_HEX_REGEX, SINGLE_LINE_COMMENT_SCHEMA,
+ SNAPSHOT_PATH_REGEX_STR, UPID,
};
const_regex! {
- pub BACKUP_NAMESPACE_REGEX = concat!(r"^", BACKUP_NS_RE!(), r"$");
+ pub BACKUP_NAMESPACE_REGEX = concatcp!(r"^", BACKUP_NS_RE, r"$");
- pub BACKUP_TYPE_REGEX = concat!(r"^(", BACKUP_TYPE_RE!(), r")$");
+ pub BACKUP_TYPE_REGEX = concatcp!(r"^(", BACKUP_TYPE_RE, r")$");
- pub BACKUP_ID_REGEX = concat!(r"^", BACKUP_ID_RE!(), r"$");
+ pub BACKUP_ID_REGEX = concatcp!(r"^", BACKUP_ID_RE, r"$");
- pub BACKUP_DATE_REGEX = concat!(r"^", BACKUP_TIME_RE!() ,r"$");
+ pub BACKUP_DATE_REGEX = concatcp!(r"^", BACKUP_TIME_RE ,r"$");
- pub GROUP_PATH_REGEX = concat!(
- r"^(", BACKUP_TYPE_RE!(), ")/",
- r"(", BACKUP_ID_RE!(), r")$",
+ pub GROUP_PATH_REGEX = concatcp!(
+ r"^(", BACKUP_TYPE_RE, ")/",
+ r"(", BACKUP_ID_RE, r")$",
);
pub BACKUP_FILE_REGEX = r"^.*\.([fd]idx|blob)$";
- pub SNAPSHOT_PATH_REGEX = concat!(r"^", SNAPSHOT_PATH_REGEX_STR!(), r"$");
- pub GROUP_OR_SNAPSHOT_PATH_REGEX = concat!(r"^", GROUP_OR_SNAPSHOT_PATH_REGEX_STR!(), r"$");
+ pub SNAPSHOT_PATH_REGEX = concatcp!(r"^", SNAPSHOT_PATH_REGEX_STR, r"$");
+ pub GROUP_OR_SNAPSHOT_PATH_REGEX = concatcp!(r"^", GROUP_OR_SNAPSHOT_PATH_REGEX_STR, r"$");
- pub DATASTORE_MAP_REGEX = concat!(r"^(?:", PROXMOX_SAFE_ID_REGEX_STR!(), r"=)?", PROXMOX_SAFE_ID_REGEX_STR!(), r"$");
+ pub DATASTORE_MAP_REGEX = concatcp!(r"^(?:", PROXMOX_SAFE_ID_REGEX_STR, r"=)?", PROXMOX_SAFE_ID_REGEX_STR, r"$");
}
pub const CHUNK_DIGEST_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&SHA256_HEX_REGEX);
diff --git a/pbs-api-types/src/jobs.rs b/pbs-api-types/src/jobs.rs
index 80578d80..6fb9b187 100644
--- a/pbs-api-types/src/jobs.rs
+++ b/pbs-api-types/src/jobs.rs
@@ -1,6 +1,7 @@
use std::str::FromStr;
use anyhow::bail;
+use const_format::concatcp;
use regex::Regex;
use serde::{Deserialize, Serialize};
@@ -8,17 +9,17 @@ use proxmox_schema::*;
use crate::{
Authid, BackupNamespace, BackupType, RateLimitConfig, Userid, BACKUP_GROUP_SCHEMA,
- BACKUP_NAMESPACE_SCHEMA, DATASTORE_SCHEMA, DRIVE_NAME_SCHEMA, MEDIA_POOL_NAME_SCHEMA,
- NS_MAX_DEPTH_REDUCED_SCHEMA, PROXMOX_SAFE_ID_FORMAT, REMOTE_ID_SCHEMA,
- SINGLE_LINE_COMMENT_SCHEMA,
+ BACKUP_NAMESPACE_SCHEMA, BACKUP_NS_RE, DATASTORE_SCHEMA, DRIVE_NAME_SCHEMA,
+ MEDIA_POOL_NAME_SCHEMA, NS_MAX_DEPTH_REDUCED_SCHEMA, PROXMOX_SAFE_ID_FORMAT,
+ PROXMOX_SAFE_ID_REGEX_STR, REMOTE_ID_SCHEMA, SINGLE_LINE_COMMENT_SCHEMA,
};
const_regex! {
/// Regex for verification jobs 'DATASTORE:ACTUAL_JOB_ID'
- pub VERIFICATION_JOB_WORKER_ID_REGEX = concat!(r"^(", PROXMOX_SAFE_ID_REGEX_STR!(), r"):");
+ pub VERIFICATION_JOB_WORKER_ID_REGEX = concatcp!(r"^(", PROXMOX_SAFE_ID_REGEX_STR, r"):");
/// Regex for sync jobs '(REMOTE|\-):REMOTE_DATASTORE:LOCAL_DATASTORE:(?:LOCAL_NS_ANCHOR:)ACTUAL_JOB_ID'
- pub SYNC_JOB_WORKER_ID_REGEX = concat!(r"^(", PROXMOX_SAFE_ID_REGEX_STR!(), r"|\-):(", PROXMOX_SAFE_ID_REGEX_STR!(), r"):(", PROXMOX_SAFE_ID_REGEX_STR!(), r")(?::(", BACKUP_NS_RE!(), r"))?:");
+ pub SYNC_JOB_WORKER_ID_REGEX = concatcp!(r"^(", PROXMOX_SAFE_ID_REGEX_STR, r"|\-):(", PROXMOX_SAFE_ID_REGEX_STR, r"):(", PROXMOX_SAFE_ID_REGEX_STR, r")(?::(", BACKUP_NS_RE, r"))?:");
}
pub const JOB_ID_SCHEMA: Schema = StringSchema::new("Job ID.")
diff --git a/pbs-api-types/src/lib.rs b/pbs-api-types/src/lib.rs
index 88e8f44d..7eb836ed 100644
--- a/pbs-api-types/src/lib.rs
+++ b/pbs-api-types/src/lib.rs
@@ -1,10 +1,8 @@
//! Basic API types used by most of the PBS code.
+use const_format::concatcp;
use serde::{Deserialize, Serialize};
-use proxmox_auth_api::{APITOKEN_ID_REGEX_STR, USER_ID_REGEX_STR};
-
-pub mod common_regex;
pub mod percent_encoding;
use proxmox_schema::{
@@ -12,59 +10,78 @@ use proxmox_schema::{
};
use proxmox_time::parse_daily_duration;
-#[rustfmt::skip]
-#[macro_export]
-macro_rules! PROXMOX_SAFE_ID_REGEX_STR { () => { r"(?:[A-Za-z0-9_][A-Za-z0-9._\-]*)" }; }
+use proxmox_auth_api::types::{APITOKEN_ID_REGEX_STR, USER_ID_REGEX_STR};
+
+pub use proxmox_schema::api_types::SAFE_ID_FORMAT as PROXMOX_SAFE_ID_FORMAT;
+pub use proxmox_schema::api_types::SAFE_ID_REGEX as PROXMOX_SAFE_ID_REGEX;
+pub use proxmox_schema::api_types::SAFE_ID_REGEX_STR as PROXMOX_SAFE_ID_REGEX_STR;
+pub use proxmox_schema::api_types::{
+ BLOCKDEVICE_DISK_AND_PARTITION_NAME_REGEX, BLOCKDEVICE_NAME_REGEX,
+};
+pub use proxmox_schema::api_types::{DNS_ALIAS_REGEX, DNS_NAME_OR_IP_REGEX, DNS_NAME_REGEX};
+pub use proxmox_schema::api_types::{FINGERPRINT_SHA256_REGEX, SHA256_HEX_REGEX};
+pub use proxmox_schema::api_types::{
+ GENERIC_URI_REGEX, HOSTNAME_REGEX, HOST_PORT_REGEX, HTTP_URL_REGEX,
+};
+pub use proxmox_schema::api_types::{MULTI_LINE_COMMENT_REGEX, SINGLE_LINE_COMMENT_REGEX};
+pub use proxmox_schema::api_types::{PASSWORD_REGEX, SYSTEMD_DATETIME_REGEX, UUID_REGEX};
+
+pub use proxmox_schema::api_types::{CIDR_FORMAT, CIDR_REGEX};
+pub use proxmox_schema::api_types::{CIDR_V4_FORMAT, CIDR_V4_REGEX};
+pub use proxmox_schema::api_types::{CIDR_V6_FORMAT, CIDR_V6_REGEX};
+pub use proxmox_schema::api_types::{IPRE_STR, IP_FORMAT, IP_REGEX};
+pub use proxmox_schema::api_types::{IPV4RE_STR, IP_V4_FORMAT, IP_V4_REGEX};
+pub use proxmox_schema::api_types::{IPV6RE_STR, IP_V6_FORMAT, IP_V6_REGEX};
+
+pub use proxmox_schema::api_types::COMMENT_SCHEMA as SINGLE_LINE_COMMENT_SCHEMA;
+pub use proxmox_schema::api_types::HOSTNAME_SCHEMA;
+pub use proxmox_schema::api_types::HOST_PORT_SCHEMA;
+pub use proxmox_schema::api_types::HTTP_URL_SCHEMA;
+pub use proxmox_schema::api_types::MULTI_LINE_COMMENT_SCHEMA;
+pub use proxmox_schema::api_types::NODE_SCHEMA;
+pub use proxmox_schema::api_types::SINGLE_LINE_COMMENT_FORMAT;
+pub use proxmox_schema::api_types::{
+ BLOCKDEVICE_DISK_AND_PARTITION_NAME_SCHEMA, BLOCKDEVICE_NAME_SCHEMA,
+};
+pub use proxmox_schema::api_types::{CERT_FINGERPRINT_SHA256_SCHEMA, FINGERPRINT_SHA256_FORMAT};
+pub use proxmox_schema::api_types::{DISK_ARRAY_SCHEMA, DISK_LIST_SCHEMA};
+pub use proxmox_schema::api_types::{DNS_ALIAS_FORMAT, DNS_NAME_FORMAT, DNS_NAME_OR_IP_SCHEMA};
+pub use proxmox_schema::api_types::{PASSWORD_FORMAT, PASSWORD_SCHEMA};
+pub use proxmox_schema::api_types::{SERVICE_ID_SCHEMA, UUID_FORMAT};
+pub use proxmox_schema::api_types::{SYSTEMD_DATETIME_FORMAT, TIME_ZONE_SCHEMA};
+
+use proxmox_schema::api_types::{DNS_NAME_STR, IPRE_BRACKET_STR};
#[rustfmt::skip]
-#[macro_export]
-macro_rules! BACKUP_ID_RE { () => (r"[A-Za-z0-9_][A-Za-z0-9._\-]*") }
+pub const BACKUP_ID_RE: &str = r"[A-Za-z0-9_][A-Za-z0-9._\-]*";
#[rustfmt::skip]
-#[macro_export]
-macro_rules! BACKUP_TYPE_RE { () => (r"(?:host|vm|ct)") }
+pub const BACKUP_TYPE_RE: &str = r"(?:host|vm|ct)";
#[rustfmt::skip]
-#[macro_export]
-macro_rules! BACKUP_TIME_RE { () => (r"[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z") }
+pub const BACKUP_TIME_RE: &str = r"[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z";
#[rustfmt::skip]
-#[macro_export]
-macro_rules! BACKUP_NS_RE {
- () => (
- concat!("(?:",
- "(?:", PROXMOX_SAFE_ID_REGEX_STR!(), r"/){0,7}", PROXMOX_SAFE_ID_REGEX_STR!(),
- ")?")
- );
-}
+pub const BACKUP_NS_RE: &str =
+ concatcp!("(?:",
+ "(?:", PROXMOX_SAFE_ID_REGEX_STR, r"/){0,7}", PROXMOX_SAFE_ID_REGEX_STR,
+ ")?");
#[rustfmt::skip]
-#[macro_export]
-macro_rules! BACKUP_NS_PATH_RE {
- () => (
- concat!(r"(?:ns/", PROXMOX_SAFE_ID_REGEX_STR!(), r"/){0,7}ns/", PROXMOX_SAFE_ID_REGEX_STR!(), r"/")
- );
-}
+pub const BACKUP_NS_PATH_RE: &str =
+ concatcp!(r"(?:ns/", PROXMOX_SAFE_ID_REGEX_STR, r"/){0,7}ns/", PROXMOX_SAFE_ID_REGEX_STR, r"/");
#[rustfmt::skip]
-#[macro_export]
-macro_rules! SNAPSHOT_PATH_REGEX_STR {
- () => (
- concat!(
- r"(", BACKUP_TYPE_RE!(), ")/(", BACKUP_ID_RE!(), ")/(", BACKUP_TIME_RE!(), r")",
- )
+pub const SNAPSHOT_PATH_REGEX_STR: &str =
+ concatcp!(
+ r"(", BACKUP_TYPE_RE, ")/(", BACKUP_ID_RE, ")/(", BACKUP_TIME_RE, r")",
);
-}
#[rustfmt::skip]
-#[macro_export]
-macro_rules! GROUP_OR_SNAPSHOT_PATH_REGEX_STR {
- () => {
- concat!(
- r"(", BACKUP_TYPE_RE!(), ")/(", BACKUP_ID_RE!(), ")(?:/(", BACKUP_TIME_RE!(), r"))?",
- )
- };
-}
+pub const GROUP_OR_SNAPSHOT_PATH_REGEX_STR: &str =
+ concatcp!(
+ r"(", BACKUP_TYPE_RE, ")/(", BACKUP_ID_RE, ")(?:/(", BACKUP_TIME_RE, r"))?",
+ );
mod acl;
pub use acl::*;
@@ -128,102 +145,28 @@ pub use zfs::*;
mod metrics;
pub use metrics::*;
-#[rustfmt::skip]
-#[macro_use]
-mod local_macros {
- macro_rules! DNS_LABEL { () => (r"(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?)") }
- macro_rules! DNS_NAME { () => (concat!(r"(?:(?:", DNS_LABEL!() , r"\.)*", DNS_LABEL!(), ")")) }
- macro_rules! CIDR_V4_REGEX_STR { () => (concat!(r"(?:", IPV4RE!(), r"/\d{1,2})$")) }
- macro_rules! CIDR_V6_REGEX_STR { () => (concat!(r"(?:", IPV6RE!(), r"/\d{1,3})$")) }
- macro_rules! DNS_ALIAS_LABEL { () => (r"(?:[a-zA-Z0-9_](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?)") }
- macro_rules! DNS_ALIAS_NAME {
- () => (concat!(r"(?:(?:", DNS_ALIAS_LABEL!() , r"\.)*", DNS_ALIAS_LABEL!(), ")"))
- }
- macro_rules! PORT_REGEX_STR { () => (r"(?:[0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])") }
-}
-
const_regex! {
- pub IP_V4_REGEX = concat!(r"^", IPV4RE!(), r"$");
- pub IP_V6_REGEX = concat!(r"^", IPV6RE!(), r"$");
- pub IP_REGEX = concat!(r"^", IPRE!(), r"$");
- pub CIDR_V4_REGEX = concat!(r"^", CIDR_V4_REGEX_STR!(), r"$");
- pub CIDR_V6_REGEX = concat!(r"^", CIDR_V6_REGEX_STR!(), r"$");
- pub CIDR_REGEX = concat!(r"^(?:", CIDR_V4_REGEX_STR!(), "|", CIDR_V6_REGEX_STR!(), r")$");
- pub HOSTNAME_REGEX = r"^(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?)$";
- pub DNS_NAME_REGEX = concat!(r"^", DNS_NAME!(), r"$");
- pub DNS_ALIAS_REGEX = concat!(r"^", DNS_ALIAS_NAME!(), r"$");
- pub DNS_NAME_OR_IP_REGEX = concat!(r"^(?:", DNS_NAME!(), "|", IPRE!(), r")$");
- pub HOST_PORT_REGEX = concat!(r"^(?:", DNS_NAME!(), "|", IPRE_BRACKET!(), "):", PORT_REGEX_STR!() ,"$");
- pub HTTP_URL_REGEX = concat!(r"^https?://(?:(?:(?:", DNS_NAME!(), "|", IPRE_BRACKET!(), ")(?::", PORT_REGEX_STR!() ,")?)|", IPV6RE!(),")(?:/[^\x00-\x1F\x7F]*)?$");
-
- pub SHA256_HEX_REGEX = r"^[a-f0-9]{64}$"; // fixme: define in common_regex ?
-
- pub PASSWORD_REGEX = r"^[[:^cntrl:]]*$"; // everything but control characters
-
- pub UUID_REGEX = r"^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$";
-
- pub SYSTEMD_DATETIME_REGEX = r"^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}(:\d{2})?)?$"; // fixme: define in common_regex ?
-
- pub FINGERPRINT_SHA256_REGEX = r"^(?:[0-9a-fA-F][0-9a-fA-F])(?::[0-9a-fA-F][0-9a-fA-F]){31}$";
-
// just a rough check - dummy acceptor is used before persisting
pub OPENSSL_CIPHERS_REGEX = r"^[0-9A-Za-z_:, +!\-@=.]+$";
- /// Regex for safe identifiers.
- ///
- /// This
- /// [article](https://dwheeler.com/essays/fixing-unix-linux-filenames.html)
- /// contains further information why it is reasonable to restict
- /// names this way. This is not only useful for filenames, but for
- /// any identifier command line tools work with.
- pub PROXMOX_SAFE_ID_REGEX = concat!(r"^", PROXMOX_SAFE_ID_REGEX_STR!(), r"$");
-
- /// Regex that (loosely) matches URIs according to [RFC 2396](https://www.rfc-editor.org/rfc/rfc2396.txt)
- /// This does not completely match a URI, but rather disallows all the prohibited characters
- /// specified in the RFC.
- pub GENERIC_URI_REGEX = r#"^[^\x00-\x1F\x7F <>#"]*$"#;
-
- pub SINGLE_LINE_COMMENT_REGEX = r"^[[:^cntrl:]]*$";
-
- pub MULTI_LINE_COMMENT_REGEX = r"(?m)^([[:^cntrl:]]*)$";
-
- pub BACKUP_REPO_URL_REGEX = concat!(
+ pub BACKUP_REPO_URL_REGEX = concatcp!(
r"^^(?:(?:(",
- USER_ID_REGEX_STR!(), "|", APITOKEN_ID_REGEX_STR!(),
+ USER_ID_REGEX_STR, "|", APITOKEN_ID_REGEX_STR,
")@)?(",
- DNS_NAME!(), "|", IPRE_BRACKET!(),
- "):)?(?:([0-9]{1,5}):)?(", PROXMOX_SAFE_ID_REGEX_STR!(), r")$"
+ DNS_NAME_STR, "|", IPRE_BRACKET_STR,
+ "):)?(?:([0-9]{1,5}):)?(", PROXMOX_SAFE_ID_REGEX_STR, r")$"
);
- pub BLOCKDEVICE_NAME_REGEX = r"^(?:(?:h|s|x?v)d[a-z]+)|(?:nvme\d+n\d+)$";
- pub BLOCKDEVICE_DISK_AND_PARTITION_NAME_REGEX = r"^(?:(?:h|s|x?v)d[a-z]+\d*)|(?:nvme\d+n\d+(p\d+)?)$";
- pub SUBSCRIPTION_KEY_REGEX = concat!(r"^pbs(?:[cbsp])-[0-9a-f]{10}$");
+ pub SUBSCRIPTION_KEY_REGEX = concat!(r"^pbs(?:[cbsp])-[0-9a-f]{10}$");
}
-pub const IP_V4_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&IP_V4_REGEX);
-pub const IP_V6_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&IP_V6_REGEX);
-pub const IP_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&IP_REGEX);
-pub const CIDR_V4_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&CIDR_V4_REGEX);
-pub const CIDR_V6_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&CIDR_V6_REGEX);
-pub const CIDR_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&CIDR_REGEX);
pub const PVE_CONFIG_DIGEST_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&SHA256_HEX_REGEX);
-pub const PASSWORD_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&PASSWORD_REGEX);
-pub const UUID_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&UUID_REGEX);
-pub const BLOCKDEVICE_NAME_FORMAT: ApiStringFormat =
- ApiStringFormat::Pattern(&BLOCKDEVICE_NAME_REGEX);
-pub const BLOCKDEVICE_DISK_AND_PARTITION_NAME_FORMAT: ApiStringFormat =
- ApiStringFormat::Pattern(&BLOCKDEVICE_DISK_AND_PARTITION_NAME_REGEX);
+
pub const SUBSCRIPTION_KEY_FORMAT: ApiStringFormat =
ApiStringFormat::Pattern(&SUBSCRIPTION_KEY_REGEX);
-pub const SYSTEMD_DATETIME_FORMAT: ApiStringFormat =
- ApiStringFormat::Pattern(&SYSTEMD_DATETIME_REGEX);
-pub const HOSTNAME_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&HOSTNAME_REGEX);
+
pub const OPENSSL_CIPHERS_TLS_FORMAT: ApiStringFormat =
ApiStringFormat::Pattern(&OPENSSL_CIPHERS_REGEX);
-pub const HOST_PORT_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&HOST_PORT_REGEX);
-pub const HTTP_URL_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&HTTP_URL_REGEX);
-
-pub const DNS_ALIAS_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&DNS_ALIAS_REGEX);
pub const DAILY_DURATION_FORMAT: ApiStringFormat =
ApiStringFormat::VerifyFn(|s| parse_daily_duration(s).map(drop));
@@ -243,10 +186,6 @@ pub const THIRD_DNS_SERVER_SCHEMA: Schema = StringSchema::new("Third name server
.format(&IP_FORMAT)
.schema();
-pub const HOSTNAME_SCHEMA: Schema = StringSchema::new("Hostname (as defined in RFC1123).")
- .format(&HOSTNAME_FORMAT)
- .schema();
-
pub const OPENSSL_CIPHERS_TLS_1_2_SCHEMA: Schema =
StringSchema::new("OpenSSL cipher list used by the proxy for TLS <= 1.2")
.format(&OPENSSL_CIPHERS_TLS_FORMAT)
@@ -257,62 +196,6 @@ pub const OPENSSL_CIPHERS_TLS_1_3_SCHEMA: Schema =
.format(&OPENSSL_CIPHERS_TLS_FORMAT)
.schema();
-pub const DNS_NAME_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&DNS_NAME_REGEX);
-
-pub const DNS_NAME_OR_IP_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&DNS_NAME_OR_IP_REGEX);
-
-pub const DNS_NAME_OR_IP_SCHEMA: Schema = StringSchema::new("DNS name or IP address.")
- .format(&DNS_NAME_OR_IP_FORMAT)
- .schema();
-
-pub const HOST_PORT_SCHEMA: Schema =
- StringSchema::new("host:port combination (Host can be DNS name or IP address).")
- .format(&HOST_PORT_FORMAT)
- .schema();
-
-pub const HTTP_URL_SCHEMA: Schema = StringSchema::new("HTTP(s) url with optional port.")
- .format(&HTTP_URL_FORMAT)
- .schema();
-
-pub const NODE_SCHEMA: Schema = StringSchema::new("Node name (or 'localhost')")
- .format(&HOSTNAME_FORMAT)
- .schema();
-
-pub const TIME_ZONE_SCHEMA: Schema = StringSchema::new(
- "Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names.",
-)
-.format(&SINGLE_LINE_COMMENT_FORMAT)
-.min_length(2)
-.max_length(64)
-.schema();
-
-pub const BLOCKDEVICE_NAME_SCHEMA: Schema =
- StringSchema::new("Block device name (/sys/block/<name>).")
- .format(&BLOCKDEVICE_NAME_FORMAT)
- .min_length(3)
- .max_length(64)
- .schema();
-
-pub const BLOCKDEVICE_DISK_AND_PARTITION_NAME_SCHEMA: Schema =
- StringSchema::new("(Partition) block device name (/sys/class/block/<name>).")
- .format(&BLOCKDEVICE_DISK_AND_PARTITION_NAME_FORMAT)
- .min_length(3)
- .max_length(64)
- .schema();
-
-pub const DISK_ARRAY_SCHEMA: Schema =
- ArraySchema::new("Disk name list.", &BLOCKDEVICE_NAME_SCHEMA).schema();
-
-pub const DISK_LIST_SCHEMA: Schema = StringSchema::new("A list of disk names, comma separated.")
- .format(&ApiStringFormat::PropertyString(&DISK_ARRAY_SCHEMA))
- .schema();
-
-pub const PASSWORD_SCHEMA: Schema = StringSchema::new("Password.")
- .format(&PASSWORD_FORMAT)
- .min_length(1)
- .max_length(1024)
- .schema();
-
pub const PBS_PASSWORD_SCHEMA: Schema = StringSchema::new("User Password.")
.format(&PASSWORD_FORMAT)
.min_length(5)
@@ -325,31 +208,6 @@ pub const REALM_ID_SCHEMA: Schema = StringSchema::new("Realm name.")
.max_length(32)
.schema();
-pub const FINGERPRINT_SHA256_FORMAT: ApiStringFormat =
- ApiStringFormat::Pattern(&FINGERPRINT_SHA256_REGEX);
-
-pub const CERT_FINGERPRINT_SHA256_SCHEMA: Schema =
- StringSchema::new("X509 certificate fingerprint (sha256).")
- .format(&FINGERPRINT_SHA256_FORMAT)
- .schema();
-
-pub const PROXMOX_SAFE_ID_FORMAT: ApiStringFormat =
- ApiStringFormat::Pattern(&PROXMOX_SAFE_ID_REGEX);
-
-pub const SINGLE_LINE_COMMENT_FORMAT: ApiStringFormat =
- ApiStringFormat::Pattern(&SINGLE_LINE_COMMENT_REGEX);
-
-pub const SINGLE_LINE_COMMENT_SCHEMA: Schema = StringSchema::new("Comment (single line).")
- .format(&SINGLE_LINE_COMMENT_FORMAT)
- .schema();
-
-pub const MULTI_LINE_COMMENT_FORMAT: ApiStringFormat =
- ApiStringFormat::Pattern(&MULTI_LINE_COMMENT_REGEX);
-
-pub const MULTI_LINE_COMMENT_SCHEMA: Schema = StringSchema::new("Comment (multiple lines).")
- .format(&MULTI_LINE_COMMENT_FORMAT)
- .schema();
-
pub const SUBSCRIPTION_KEY_SCHEMA: Schema =
StringSchema::new("Proxmox Backup Server subscription key.")
.format(&SUBSCRIPTION_KEY_FORMAT)
@@ -357,8 +215,6 @@ pub const SUBSCRIPTION_KEY_SCHEMA: Schema =
.max_length(16)
.schema();
-pub const SERVICE_ID_SCHEMA: Schema = StringSchema::new("Service ID.").max_length(256).schema();
-
pub const PROXMOX_CONFIG_DIGEST_SCHEMA: Schema = StringSchema::new(
"Prevent changes if current configuration file has different \
SHA256 digest. This can be used to prevent concurrent \
diff --git a/pbs-api-types/src/tape/mod.rs b/pbs-api-types/src/tape/mod.rs
index 99d7cb74..6a9d56bc 100644
--- a/pbs-api-types/src/tape/mod.rs
+++ b/pbs-api-types/src/tape/mod.rs
@@ -22,15 +22,19 @@ pub use media_location::*;
mod media;
pub use media::*;
+use const_format::concatcp;
use serde::{Deserialize, Serialize};
use proxmox_schema::{api, const_regex, ApiStringFormat, Schema, StringSchema};
use proxmox_uuid::Uuid;
-use crate::{BackupType, BACKUP_ID_SCHEMA, FINGERPRINT_SHA256_FORMAT};
+use crate::{
+ BackupType, BACKUP_ID_SCHEMA, BACKUP_NS_PATH_RE, FINGERPRINT_SHA256_FORMAT,
+ PROXMOX_SAFE_ID_REGEX_STR, SNAPSHOT_PATH_REGEX_STR,
+};
const_regex! {
- pub TAPE_RESTORE_SNAPSHOT_REGEX = concat!(r"^", PROXMOX_SAFE_ID_REGEX_STR!(), r":(?:", BACKUP_NS_PATH_RE!(),")?", SNAPSHOT_PATH_REGEX_STR!(), r"$");
+ pub TAPE_RESTORE_SNAPSHOT_REGEX = concatcp!(r"^", PROXMOX_SAFE_ID_REGEX_STR, r":(?:", BACKUP_NS_PATH_RE,")?", SNAPSHOT_PATH_REGEX_STR, r"$");
}
pub const TAPE_RESTORE_SNAPSHOT_FORMAT: ApiStringFormat =
diff --git a/pbs-config/src/network/helper.rs b/pbs-config/src/network/helper.rs
index 7180aaaa..1cf41431 100644
--- a/pbs-config/src/network/helper.rs
+++ b/pbs-config/src/network/helper.rs
@@ -89,13 +89,6 @@ pub fn check_netmask(mask: u8, is_v6: bool) -> Result<(), Error> {
// parse ip address with optional cidr mask
pub fn parse_address_or_cidr(cidr: &str) -> Result<(String, Option<u8>, bool), Error> {
- lazy_static! {
- pub static ref CIDR_V4_REGEX: Regex =
- Regex::new(concat!(r"^(", IPV4RE!(), r")(?:/(\d{1,2}))?$")).unwrap();
- pub static ref CIDR_V6_REGEX: Regex =
- Regex::new(concat!(r"^(", IPV6RE!(), r")(?:/(\d{1,3}))?$")).unwrap();
- }
-
if let Some(caps) = CIDR_V4_REGEX.captures(cidr) {
let address = &caps[1];
if let Some(mask) = caps.get(2) {
diff --git a/pbs-config/src/network/parser.rs b/pbs-config/src/network/parser.rs
index 2cff6587..ec2c64eb 100644
--- a/pbs-config/src/network/parser.rs
+++ b/pbs-config/src/network/parser.rs
@@ -192,7 +192,7 @@ impl<R: BufRead> NetworkParser<R> {
self.eat(Token::Gateway)?;
let gateway = self.next_text()?;
- if pbs_api_types::common_regex::IP_REGEX.is_match(&gateway) {
+ if pbs_api_types::IP_REGEX.is_match(&gateway) {
if gateway.contains(':') {
set_gateway_v6(interface, gateway)?;
} else {
diff --git a/src/api2/node/dns.rs b/src/api2/node/dns.rs
index 4f6822d8..87a11738 100644
--- a/src/api2/node/dns.rs
+++ b/src/api2/node/dns.rs
@@ -2,12 +2,14 @@ use std::sync::{Arc, Mutex};
use ::serde::{Deserialize, Serialize};
use anyhow::Error;
+use const_format::concatcp;
use lazy_static::lazy_static;
use openssl::sha;
use regex::Regex;
use serde_json::{json, Value};
-use pbs_api_types::{IPRE, IPV4OCTET, IPV4RE, IPV6H16, IPV6LS32, IPV6RE};
+use pbs_api_types::IPRE_STR;
+
use proxmox_router::{ApiMethod, Permission, Router, RpcEnvironment};
use proxmox_schema::api;
use proxmox_sys::fs::{file_get_contents, replace_file, CreateOptions};
@@ -47,7 +49,7 @@ pub fn read_etc_resolv_conf() -> Result<Value, Error> {
lazy_static! {
static ref DOMAIN_REGEX: Regex = Regex::new(r"^\s*(?:search|domain)\s+(\S+)\s*").unwrap();
static ref SERVER_REGEX: Regex =
- Regex::new(concat!(r"^\s*nameserver\s+(", IPRE!(), r")\s*")).unwrap();
+ Regex::new(concatcp!(r"^\s*nameserver\s+(", IPRE_STR, r")\s*")).unwrap();
}
let mut options = String::new();
--
2.39.2
More information about the pbs-devel
mailing list