mirror of
git://git.proxmox.com/git/proxmox-backup.git
synced 2025-01-24 02:04:14 +03:00
pbs-api-types: use const_format and new api-types from proxmox-schema
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
This commit is contained in:
parent
ffc62ac94d
commit
2416aea8d4
@ -108,6 +108,7 @@ bitflags = "1.2.1"
|
|||||||
bytes = "1.0"
|
bytes = "1.0"
|
||||||
cidr = "0.2.1"
|
cidr = "0.2.1"
|
||||||
crc32fast = "1"
|
crc32fast = "1"
|
||||||
|
const_format = "0.2"
|
||||||
crossbeam-channel = "0.5"
|
crossbeam-channel = "0.5"
|
||||||
endian_trait = { version = "0.6", features = ["arrays"] }
|
endian_trait = { version = "0.6", features = ["arrays"] }
|
||||||
env_logger = "0.10"
|
env_logger = "0.10"
|
||||||
@ -158,6 +159,7 @@ base64.workspace = true
|
|||||||
bitflags.workspace = true
|
bitflags.workspace = true
|
||||||
bytes.workspace = true
|
bytes.workspace = true
|
||||||
cidr.workspace = true
|
cidr.workspace = true
|
||||||
|
const_format.workspace = true
|
||||||
crc32fast.workspace = true
|
crc32fast.workspace = true
|
||||||
crossbeam-channel.workspace = true
|
crossbeam-channel.workspace = true
|
||||||
endian_trait.workspace = true
|
endian_trait.workspace = true
|
||||||
|
@ -7,6 +7,7 @@ description = "general API type helpers for PBS"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
|
const_format.workspace = true
|
||||||
hex.workspace = true
|
hex.workspace = true
|
||||||
lazy_static.workspace = true
|
lazy_static.workspace = true
|
||||||
percent-encoding.workspace = true
|
percent-encoding.workspace = true
|
||||||
|
@ -2,14 +2,17 @@ use std::str::FromStr;
|
|||||||
|
|
||||||
use serde::de::{value, IntoDeserializer};
|
use serde::de::{value, IntoDeserializer};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use const_format::concatcp;
|
||||||
|
|
||||||
use proxmox_lang::constnamedbitmap;
|
use proxmox_lang::constnamedbitmap;
|
||||||
use proxmox_schema::{
|
use proxmox_schema::{
|
||||||
api, const_regex, ApiStringFormat, BooleanSchema, EnumEntry, Schema, StringSchema,
|
api, const_regex, ApiStringFormat, BooleanSchema, EnumEntry, Schema, StringSchema,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::PROXMOX_SAFE_ID_REGEX_STR;
|
||||||
|
|
||||||
const_regex! {
|
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
|
// define Privilege bitfield
|
||||||
|
@ -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]"));
|
|
||||||
}
|
|
@ -2,6 +2,7 @@ use std::fmt;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
|
use const_format::concatcp;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use proxmox_schema::{
|
use proxmox_schema::{
|
||||||
@ -10,31 +11,33 @@ use proxmox_schema::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Authid, CryptMode, Fingerprint, GroupFilter, MaintenanceMode, Userid,
|
Authid, CryptMode, Fingerprint, GroupFilter, MaintenanceMode, Userid, BACKUP_ID_RE,
|
||||||
DATASTORE_NOTIFY_STRING_SCHEMA, GC_SCHEDULE_SCHEMA, PROXMOX_SAFE_ID_FORMAT,
|
BACKUP_NS_RE, BACKUP_TIME_RE, BACKUP_TYPE_RE, DATASTORE_NOTIFY_STRING_SCHEMA,
|
||||||
PRUNE_SCHEDULE_SCHEMA, SHA256_HEX_REGEX, SINGLE_LINE_COMMENT_SCHEMA, UPID,
|
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! {
|
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!(
|
pub GROUP_PATH_REGEX = concatcp!(
|
||||||
r"^(", BACKUP_TYPE_RE!(), ")/",
|
r"^(", BACKUP_TYPE_RE, ")/",
|
||||||
r"(", BACKUP_ID_RE!(), r")$",
|
r"(", BACKUP_ID_RE, r")$",
|
||||||
);
|
);
|
||||||
|
|
||||||
pub BACKUP_FILE_REGEX = r"^.*\.([fd]idx|blob)$";
|
pub BACKUP_FILE_REGEX = r"^.*\.([fd]idx|blob)$";
|
||||||
|
|
||||||
pub SNAPSHOT_PATH_REGEX = concat!(r"^", SNAPSHOT_PATH_REGEX_STR!(), r"$");
|
pub SNAPSHOT_PATH_REGEX = concatcp!(r"^", SNAPSHOT_PATH_REGEX_STR, r"$");
|
||||||
pub GROUP_OR_SNAPSHOT_PATH_REGEX = concat!(r"^", GROUP_OR_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);
|
pub const CHUNK_DIGEST_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&SHA256_HEX_REGEX);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
|
use const_format::concatcp;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -8,17 +9,17 @@ use proxmox_schema::*;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Authid, BackupNamespace, BackupType, RateLimitConfig, Userid, BACKUP_GROUP_SCHEMA,
|
Authid, BackupNamespace, BackupType, RateLimitConfig, Userid, BACKUP_GROUP_SCHEMA,
|
||||||
BACKUP_NAMESPACE_SCHEMA, DATASTORE_SCHEMA, DRIVE_NAME_SCHEMA, MEDIA_POOL_NAME_SCHEMA,
|
BACKUP_NAMESPACE_SCHEMA, BACKUP_NS_RE, DATASTORE_SCHEMA, DRIVE_NAME_SCHEMA,
|
||||||
NS_MAX_DEPTH_REDUCED_SCHEMA, PROXMOX_SAFE_ID_FORMAT, REMOTE_ID_SCHEMA,
|
MEDIA_POOL_NAME_SCHEMA, NS_MAX_DEPTH_REDUCED_SCHEMA, PROXMOX_SAFE_ID_FORMAT,
|
||||||
SINGLE_LINE_COMMENT_SCHEMA,
|
PROXMOX_SAFE_ID_REGEX_STR, REMOTE_ID_SCHEMA, SINGLE_LINE_COMMENT_SCHEMA,
|
||||||
};
|
};
|
||||||
|
|
||||||
const_regex! {
|
const_regex! {
|
||||||
|
|
||||||
/// Regex for verification jobs 'DATASTORE:ACTUAL_JOB_ID'
|
/// 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'
|
/// 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.")
|
pub const JOB_ID_SCHEMA: Schema = StringSchema::new("Job ID.")
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
//! Basic API types used by most of the PBS code.
|
//! Basic API types used by most of the PBS code.
|
||||||
|
|
||||||
|
use const_format::concatcp;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use proxmox_auth_api::{APITOKEN_ID_REGEX_STR, USER_ID_REGEX_STR};
|
|
||||||
|
|
||||||
pub mod common_regex;
|
|
||||||
pub mod percent_encoding;
|
pub mod percent_encoding;
|
||||||
|
|
||||||
use proxmox_schema::{
|
use proxmox_schema::{
|
||||||
@ -12,59 +10,78 @@ use proxmox_schema::{
|
|||||||
};
|
};
|
||||||
use proxmox_time::parse_daily_duration;
|
use proxmox_time::parse_daily_duration;
|
||||||
|
|
||||||
#[rustfmt::skip]
|
use proxmox_auth_api::types::{APITOKEN_ID_REGEX_STR, USER_ID_REGEX_STR};
|
||||||
#[macro_export]
|
|
||||||
macro_rules! PROXMOX_SAFE_ID_REGEX_STR { () => { r"(?:[A-Za-z0-9_][A-Za-z0-9._\-]*)" }; }
|
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]
|
#[rustfmt::skip]
|
||||||
#[macro_export]
|
pub const BACKUP_ID_RE: &str = r"[A-Za-z0-9_][A-Za-z0-9._\-]*";
|
||||||
macro_rules! BACKUP_ID_RE { () => (r"[A-Za-z0-9_][A-Za-z0-9._\-]*") }
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
#[macro_export]
|
pub const BACKUP_TYPE_RE: &str = r"(?:host|vm|ct)";
|
||||||
macro_rules! BACKUP_TYPE_RE { () => (r"(?:host|vm|ct)") }
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
#[macro_export]
|
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";
|
||||||
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") }
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
#[macro_export]
|
pub const BACKUP_NS_RE: &str =
|
||||||
macro_rules! BACKUP_NS_RE {
|
concatcp!("(?:",
|
||||||
() => (
|
"(?:", PROXMOX_SAFE_ID_REGEX_STR, r"/){0,7}", PROXMOX_SAFE_ID_REGEX_STR,
|
||||||
concat!("(?:",
|
")?");
|
||||||
"(?:", PROXMOX_SAFE_ID_REGEX_STR!(), r"/){0,7}", PROXMOX_SAFE_ID_REGEX_STR!(),
|
|
||||||
")?")
|
#[rustfmt::skip]
|
||||||
|
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]
|
||||||
|
pub const SNAPSHOT_PATH_REGEX_STR: &str =
|
||||||
|
concatcp!(
|
||||||
|
r"(", BACKUP_TYPE_RE, ")/(", BACKUP_ID_RE, ")/(", BACKUP_TIME_RE, r")",
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
#[macro_export]
|
pub const GROUP_OR_SNAPSHOT_PATH_REGEX_STR: &str =
|
||||||
macro_rules! BACKUP_NS_PATH_RE {
|
concatcp!(
|
||||||
() => (
|
r"(", BACKUP_TYPE_RE, ")/(", BACKUP_ID_RE, ")(?:/(", BACKUP_TIME_RE, r"))?",
|
||||||
concat!(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")",
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! GROUP_OR_SNAPSHOT_PATH_REGEX_STR {
|
|
||||||
() => {
|
|
||||||
concat!(
|
|
||||||
r"(", BACKUP_TYPE_RE!(), ")/(", BACKUP_ID_RE!(), ")(?:/(", BACKUP_TIME_RE!(), r"))?",
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
mod acl;
|
mod acl;
|
||||||
pub use acl::*;
|
pub use acl::*;
|
||||||
@ -128,102 +145,28 @@ pub use zfs::*;
|
|||||||
mod metrics;
|
mod metrics;
|
||||||
pub use 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! {
|
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
|
// just a rough check - dummy acceptor is used before persisting
|
||||||
pub OPENSSL_CIPHERS_REGEX = r"^[0-9A-Za-z_:, +!\-@=.]+$";
|
pub OPENSSL_CIPHERS_REGEX = r"^[0-9A-Za-z_:, +!\-@=.]+$";
|
||||||
|
|
||||||
/// Regex for safe identifiers.
|
pub BACKUP_REPO_URL_REGEX = concatcp!(
|
||||||
///
|
|
||||||
/// 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!(
|
|
||||||
r"^^(?:(?:(",
|
r"^^(?:(?:(",
|
||||||
USER_ID_REGEX_STR!(), "|", APITOKEN_ID_REGEX_STR!(),
|
USER_ID_REGEX_STR, "|", APITOKEN_ID_REGEX_STR,
|
||||||
")@)?(",
|
")@)?(",
|
||||||
DNS_NAME!(), "|", IPRE_BRACKET!(),
|
DNS_NAME_STR, "|", IPRE_BRACKET_STR,
|
||||||
"):)?(?:([0-9]{1,5}):)?(", PROXMOX_SAFE_ID_REGEX_STR!(), r")$"
|
"):)?(?:([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 SUBSCRIPTION_KEY_REGEX = concat!(r"^pbs(?:[cbsp])-[0-9a-f]{10}$");
|
||||||
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 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 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 =
|
pub const SUBSCRIPTION_KEY_FORMAT: ApiStringFormat =
|
||||||
ApiStringFormat::Pattern(&SUBSCRIPTION_KEY_REGEX);
|
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 =
|
pub const OPENSSL_CIPHERS_TLS_FORMAT: ApiStringFormat =
|
||||||
ApiStringFormat::Pattern(&OPENSSL_CIPHERS_REGEX);
|
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 =
|
pub const DAILY_DURATION_FORMAT: ApiStringFormat =
|
||||||
ApiStringFormat::VerifyFn(|s| parse_daily_duration(s).map(drop));
|
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)
|
.format(&IP_FORMAT)
|
||||||
.schema();
|
.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 =
|
pub const OPENSSL_CIPHERS_TLS_1_2_SCHEMA: Schema =
|
||||||
StringSchema::new("OpenSSL cipher list used by the proxy for TLS <= 1.2")
|
StringSchema::new("OpenSSL cipher list used by the proxy for TLS <= 1.2")
|
||||||
.format(&OPENSSL_CIPHERS_TLS_FORMAT)
|
.format(&OPENSSL_CIPHERS_TLS_FORMAT)
|
||||||
@ -257,62 +196,6 @@ pub const OPENSSL_CIPHERS_TLS_1_3_SCHEMA: Schema =
|
|||||||
.format(&OPENSSL_CIPHERS_TLS_FORMAT)
|
.format(&OPENSSL_CIPHERS_TLS_FORMAT)
|
||||||
.schema();
|
.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.")
|
pub const PBS_PASSWORD_SCHEMA: Schema = StringSchema::new("User Password.")
|
||||||
.format(&PASSWORD_FORMAT)
|
.format(&PASSWORD_FORMAT)
|
||||||
.min_length(5)
|
.min_length(5)
|
||||||
@ -325,31 +208,6 @@ pub const REALM_ID_SCHEMA: Schema = StringSchema::new("Realm name.")
|
|||||||
.max_length(32)
|
.max_length(32)
|
||||||
.schema();
|
.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 =
|
pub const SUBSCRIPTION_KEY_SCHEMA: Schema =
|
||||||
StringSchema::new("Proxmox Backup Server subscription key.")
|
StringSchema::new("Proxmox Backup Server subscription key.")
|
||||||
.format(&SUBSCRIPTION_KEY_FORMAT)
|
.format(&SUBSCRIPTION_KEY_FORMAT)
|
||||||
@ -357,8 +215,6 @@ pub const SUBSCRIPTION_KEY_SCHEMA: Schema =
|
|||||||
.max_length(16)
|
.max_length(16)
|
||||||
.schema();
|
.schema();
|
||||||
|
|
||||||
pub const SERVICE_ID_SCHEMA: Schema = StringSchema::new("Service ID.").max_length(256).schema();
|
|
||||||
|
|
||||||
pub const PROXMOX_CONFIG_DIGEST_SCHEMA: Schema = StringSchema::new(
|
pub const PROXMOX_CONFIG_DIGEST_SCHEMA: Schema = StringSchema::new(
|
||||||
"Prevent changes if current configuration file has different \
|
"Prevent changes if current configuration file has different \
|
||||||
SHA256 digest. This can be used to prevent concurrent \
|
SHA256 digest. This can be used to prevent concurrent \
|
||||||
|
@ -22,15 +22,19 @@ pub use media_location::*;
|
|||||||
mod media;
|
mod media;
|
||||||
pub use media::*;
|
pub use media::*;
|
||||||
|
|
||||||
|
use const_format::concatcp;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use proxmox_schema::{api, const_regex, ApiStringFormat, Schema, StringSchema};
|
use proxmox_schema::{api, const_regex, ApiStringFormat, Schema, StringSchema};
|
||||||
use proxmox_uuid::Uuid;
|
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! {
|
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 =
|
pub const TAPE_RESTORE_SNAPSHOT_FORMAT: ApiStringFormat =
|
||||||
|
@ -89,13 +89,6 @@ pub fn check_netmask(mask: u8, is_v6: bool) -> Result<(), Error> {
|
|||||||
|
|
||||||
// parse ip address with optional cidr mask
|
// parse ip address with optional cidr mask
|
||||||
pub fn parse_address_or_cidr(cidr: &str) -> Result<(String, Option<u8>, bool), Error> {
|
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) {
|
if let Some(caps) = CIDR_V4_REGEX.captures(cidr) {
|
||||||
let address = &caps[1];
|
let address = &caps[1];
|
||||||
if let Some(mask) = caps.get(2) {
|
if let Some(mask) = caps.get(2) {
|
||||||
|
@ -192,7 +192,7 @@ impl<R: BufRead> NetworkParser<R> {
|
|||||||
self.eat(Token::Gateway)?;
|
self.eat(Token::Gateway)?;
|
||||||
let gateway = self.next_text()?;
|
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(':') {
|
if gateway.contains(':') {
|
||||||
set_gateway_v6(interface, gateway)?;
|
set_gateway_v6(interface, gateway)?;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,12 +2,14 @@ use std::sync::{Arc, Mutex};
|
|||||||
|
|
||||||
use ::serde::{Deserialize, Serialize};
|
use ::serde::{Deserialize, Serialize};
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
|
use const_format::concatcp;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use openssl::sha;
|
use openssl::sha;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde_json::{json, Value};
|
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_router::{ApiMethod, Permission, Router, RpcEnvironment};
|
||||||
use proxmox_schema::api;
|
use proxmox_schema::api;
|
||||||
use proxmox_sys::fs::{file_get_contents, replace_file, CreateOptions};
|
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! {
|
lazy_static! {
|
||||||
static ref DOMAIN_REGEX: Regex = Regex::new(r"^\s*(?:search|domain)\s+(\S+)\s*").unwrap();
|
static ref DOMAIN_REGEX: Regex = Regex::new(r"^\s*(?:search|domain)\s+(\S+)\s*").unwrap();
|
||||||
static ref SERVER_REGEX: Regex =
|
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();
|
let mut options = String::new();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user