public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pbs-devel] [PATCH proxmox 1/4] proxmox-schema: use const_format to define static strings.
@ 2024-03-15 11:27 Dietmar Maurer
  2024-03-15 11:27 ` [pbs-devel] [PATCH proxmox 2/4] proxmox-auth-api: " Dietmar Maurer
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Dietmar Maurer @ 2024-03-15 11:27 UTC (permalink / raw)
  To: pbs-devel

Macro rules are not hygienic, and current rust macro visibility rules
are a nightmare. Using const_format::concatcp!() is a much cleaner
solution.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
---
 Cargo.toml                      |  1 +
 proxmox-schema/Cargo.toml       |  3 ++-
 proxmox-schema/src/api_types.rs | 12 +++++++-----
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 58d5a67..032ef65 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -55,6 +55,7 @@ base32 = "0.4"
 base64 = "0.13"
 bitflags = "1.2.1"
 bytes = "1.0"
+const_format = "0.2"
 crc32fast = "1"
 crossbeam-channel = "0.5"
 endian_trait = "0.6"
diff --git a/proxmox-schema/Cargo.toml b/proxmox-schema/Cargo.toml
index ae06818..1c150b2 100644
--- a/proxmox-schema/Cargo.toml
+++ b/proxmox-schema/Cargo.toml
@@ -11,6 +11,7 @@ exclude.workspace = true
 
 [dependencies]
 anyhow.workspace = true
+const_format = { workspace = true, optional = true }
 lazy_static.workspace = true
 regex.workspace = true
 serde.workspace = true
@@ -33,7 +34,7 @@ default = []
 
 api-macro = ["dep:proxmox-api-macro"]
 upid-api-impl = [ "dep:libc", "dep:nix" ]
-api-types = []
+api-types = [ "dep:const_format" ]
 
 # Testing only
 test-harness = []
diff --git a/proxmox-schema/src/api_types.rs b/proxmox-schema/src/api_types.rs
index 0cec043..4e10ebb 100644
--- a/proxmox-schema/src/api_types.rs
+++ b/proxmox-schema/src/api_types.rs
@@ -1,10 +1,10 @@
 //! The "basic" api types we generally require along with some of their macros.
+use const_format::concatcp;
 
 use crate::{ApiStringFormat, Schema, StringSchema};
 
 #[rustfmt::skip]
-#[macro_export]
-macro_rules! SAFE_ID_REGEX_STR { () => { r"(?:[A-Za-z0-9_][A-Za-z0-9._\-]*)" }; }
+const SAFE_ID_REGEX_STR: &str = r"(?:[A-Za-z0-9_][A-Za-z0-9._\-]*)";
 
 const_regex! {
     /// Regex for safe identifiers.
@@ -14,9 +14,11 @@ const_regex! {
     /// 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 SAFE_ID_REGEX = concat!(r"^", SAFE_ID_REGEX_STR!(), r"$");
-    pub PASSWORD_REGEX = r"^[[:^cntrl:]]*$"; // everything but control characters
-    pub SINGLE_LINE_COMMENT_REGEX = r"^[[:^cntrl:]]*$"; // everything but control characters
+    pub SAFE_ID_REGEX = concatcp!(r"^", SAFE_ID_REGEX_STR, r"$");
+    /// Password. Allow everything but control characters.
+    pub PASSWORD_REGEX = r"^[[:^cntrl:]]*$";
+    /// Single line comment. Allow everything but control characters.
+    pub SINGLE_LINE_COMMENT_REGEX = r"^[[:^cntrl:]]*$";
 }
 
 pub const SAFE_ID_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&SAFE_ID_REGEX);
-- 
2.39.2




^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pbs-devel] [PATCH proxmox 2/4] proxmox-auth-api: use const_format to define static strings
  2024-03-15 11:27 [pbs-devel] [PATCH proxmox 1/4] proxmox-schema: use const_format to define static strings Dietmar Maurer
@ 2024-03-15 11:27 ` Dietmar Maurer
  2024-03-15 11:27 ` [pbs-devel] [PATCH proxmox 3/4] proxmox-schema: add IP address regex/api-types Dietmar Maurer
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Dietmar Maurer @ 2024-03-15 11:27 UTC (permalink / raw)
  To: pbs-devel

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
---
 proxmox-auth-api/Cargo.toml   |  4 +--
 proxmox-auth-api/src/types.rs | 62 ++++++++++-------------------------
 2 files changed, 20 insertions(+), 46 deletions(-)

diff --git a/proxmox-auth-api/Cargo.toml b/proxmox-auth-api/Cargo.toml
index 6e4a626..ecea701 100644
--- a/proxmox-auth-api/Cargo.toml
+++ b/proxmox-auth-api/Cargo.toml
@@ -14,7 +14,7 @@ required-features = [ "pam-authenticator" ]
 
 [dependencies]
 anyhow.workspace = true
-
+const_format = { workspace = true, optional = true }
 base64 = { workspace = true, optional = true }
 lazy_static = { workspace = true, optional = true }
 libc = { workspace = true, optional = true }
@@ -37,7 +37,7 @@ proxmox-tfa = { workspace = true, optional = true, features = [ "api" ] }
 default = []
 
 ticket = [ "dep:base64", "dep:percent-encoding", "dep:openssl" ]
-api-types = [ "dep:lazy_static", "dep:regex", "dep:serde", "dep:serde_plain", "dep:proxmox-schema" ]
+api-types = [ "dep:const_format", "dep:lazy_static", "dep:regex", "dep:serde", "dep:serde_plain", "dep:proxmox-schema" ]
 api = [
     "api-types",
     "ticket",
diff --git a/proxmox-auth-api/src/types.rs b/proxmox-auth-api/src/types.rs
index 319ac4b..e11d0b1 100644
--- a/proxmox-auth-api/src/types.rs
+++ b/proxmox-auth-api/src/types.rs
@@ -27,62 +27,36 @@ use std::fmt;
 use anyhow::{bail, format_err, Error};
 use lazy_static::lazy_static;
 use serde::{Deserialize, Serialize};
+use const_format::concatcp;
 
 use proxmox_schema::{
     api, const_regex, ApiStringFormat, ApiType, Schema, StringSchema, UpdaterType,
 };
 
+use proxmox_schema::api_types::SAFE_ID_REGEX_STR;
+
 // we only allow a limited set of characters
 // colon is not allowed, because we store usernames in
 // colon separated lists)!
 // slash is not allowed because it is used as pve API delimiter
 // also see "man useradd"
-#[macro_export]
-macro_rules! USER_NAME_REGEX_STR {
-    () => {
-        r"(?:[^\s:/[:cntrl:]]+)"
-    };
-}
-#[macro_export]
-macro_rules! GROUP_NAME_REGEX_STR {
-    () => {
-        $crate::USER_NAME_REGEX_STR!()
-    };
-}
-#[macro_export]
-macro_rules! TOKEN_NAME_REGEX_STR {
-    () => {
-        proxmox_schema::SAFE_ID_REGEX_STR!()
-    };
-}
-#[macro_export]
-macro_rules! USER_ID_REGEX_STR {
-    () => {
-        concat!(
-            $crate::USER_NAME_REGEX_STR!(),
-            r"@",
-            proxmox_schema::SAFE_ID_REGEX_STR!()
-        )
-    };
-}
-#[macro_export]
-macro_rules! APITOKEN_ID_REGEX_STR {
-    () => {
-        concat!(
-            $crate::USER_ID_REGEX_STR!(),
-            r"!",
-            $crate::TOKEN_NAME_REGEX_STR!()
-        )
-    };
-}
+pub const USER_NAME_REGEX_STR: &str = r"(?:[^\s:/[:cntrl:]]+)";
+
+pub const GROUP_NAME_REGEX_STR: &str = USER_NAME_REGEX_STR;
+
+pub const TOKEN_NAME_REGEX_STR: &str = SAFE_ID_REGEX_STR;
+
+pub const USER_ID_REGEX_STR: &str = concatcp!(USER_NAME_REGEX_STR, r"@", SAFE_ID_REGEX_STR);
+
+pub const APITOKEN_ID_REGEX_STR: &str = concatcp!(USER_ID_REGEX_STR, r"!", TOKEN_NAME_REGEX_STR);
 
 const_regex! {
-    pub PROXMOX_USER_NAME_REGEX = concat!(r"^",  USER_NAME_REGEX_STR!(), r"$");
-    pub PROXMOX_TOKEN_NAME_REGEX = concat!(r"^", TOKEN_NAME_REGEX_STR!(), r"$");
-    pub PROXMOX_USER_ID_REGEX = concat!(r"^",  USER_ID_REGEX_STR!(), r"$");
-    pub PROXMOX_APITOKEN_ID_REGEX = concat!(r"^", APITOKEN_ID_REGEX_STR!(), r"$");
-    pub PROXMOX_AUTH_ID_REGEX = concat!(r"^", r"(?:", USER_ID_REGEX_STR!(), r"|", APITOKEN_ID_REGEX_STR!(), r")$");
-    pub PROXMOX_GROUP_ID_REGEX = concat!(r"^",  GROUP_NAME_REGEX_STR!(), r"$");
+    pub PROXMOX_USER_NAME_REGEX = concatcp!(r"^",  USER_NAME_REGEX_STR, r"$");
+    pub PROXMOX_TOKEN_NAME_REGEX = concatcp!(r"^", TOKEN_NAME_REGEX_STR, r"$");
+    pub PROXMOX_USER_ID_REGEX = concatcp!(r"^",  USER_ID_REGEX_STR, r"$");
+    pub PROXMOX_APITOKEN_ID_REGEX = concatcp!(r"^", APITOKEN_ID_REGEX_STR, r"$");
+    pub PROXMOX_AUTH_ID_REGEX = concatcp!(r"^", r"(?:", USER_ID_REGEX_STR, r"|", APITOKEN_ID_REGEX_STR, r")$");
+    pub PROXMOX_GROUP_ID_REGEX = concatcp!(r"^",  GROUP_NAME_REGEX_STR, r"$");
 }
 
 pub const PROXMOX_USER_NAME_FORMAT: ApiStringFormat =
-- 
2.39.2




^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pbs-devel] [PATCH proxmox 3/4] proxmox-schema: add IP address regex/api-types
  2024-03-15 11:27 [pbs-devel] [PATCH proxmox 1/4] proxmox-schema: use const_format to define static strings Dietmar Maurer
  2024-03-15 11:27 ` [pbs-devel] [PATCH proxmox 2/4] proxmox-auth-api: " Dietmar Maurer
@ 2024-03-15 11:27 ` Dietmar Maurer
  2024-03-15 11:27 ` [pbs-devel] [PATCH proxmox 4/4] proxmox-schema: moved common api types from pbs-api-types Dietmar Maurer
  2024-03-19 10:14 ` [pbs-devel] applied-series: [PATCH proxmox 1/4] proxmox-schema: use const_format to define static strings Wolfgang Bumiller
  3 siblings, 0 replies; 5+ messages in thread
From: Dietmar Maurer @ 2024-03-15 11:27 UTC (permalink / raw)
  To: pbs-devel

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
---
 proxmox-schema/src/api_types.rs | 84 +++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/proxmox-schema/src/api_types.rs b/proxmox-schema/src/api_types.rs
index 4e10ebb..381d4cb 100644
--- a/proxmox-schema/src/api_types.rs
+++ b/proxmox-schema/src/api_types.rs
@@ -3,10 +3,68 @@ use const_format::concatcp;
 
 use crate::{ApiStringFormat, Schema, StringSchema};
 
+#[rustfmt::skip]
+const IPV4OCTET: &str = r"(?:25[0-5]|(?:2[0-4]|1[0-9]|[1-9])?[0-9])";
+
+#[rustfmt::skip]
+const IPV6H16: &str = r"(?:[0-9a-fA-F]{1,4})";
+
+/// Returns the regular expression string to match IPv4 addresses
+#[rustfmt::skip]
+pub const IPV4RE_STR: &str = concatcp!(r"(?:(?:", IPV4OCTET, r"\.){3}", IPV4OCTET, ")");
+
+#[rustfmt::skip]
+const IPV6LS32: &str = concatcp!(r"(?:(?:", IPV4RE_STR, "|", IPV6H16, ":", IPV6H16, "))" );
+
+/// Returns the regular expression string to match IPv6 addresses
+#[rustfmt::skip]
+pub const IPV6RE_STR: &str = concatcp!(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]
+pub const IPRE_STR: &str = concatcp!(r"(?:", IPV4RE_STR, "|", IPV6RE_STR, ")");
+
+/// Regular expression string to match IP addresses where IPv6 addresses require brackets around
+/// them, while for IPv4 they are forbidden.
+#[rustfmt::skip]
+pub const IPRE_BRACKET_STR: &str = concatcp!(r"(?:", IPV4RE_STR, r"|\[(?:", IPV6RE_STR, r")\]", r")");
+
+#[rustfmt::skip]
+pub const CIDR_V4_REGEX_STR: &str = concatcp!(r"(?:", IPV4RE_STR, r"/\d{1,2})$");
+
+#[rustfmt::skip]
+pub const CIDR_V6_REGEX_STR: &str = concatcp!(r"(?:", IPV6RE_STR, r"/\d{1,3})$");
+
 #[rustfmt::skip]
 const SAFE_ID_REGEX_STR: &str = r"(?:[A-Za-z0-9_][A-Za-z0-9._\-]*)";
 
 const_regex! {
+    /// IPv4 regular expression.
+    pub IP_V4_REGEX = concatcp!(r"^", IPV4RE_STR, r"$");
+
+    /// IPv6 regular expression.
+    pub IP_V6_REGEX = concatcp!(r"^", IPV6RE_STR, r"$");
+
+    /// Regex to match IP addresses (V4 or V6)
+    pub IP_REGEX = concatcp!(r"^", IPRE_STR, r"$");
+
+    /// Regex to match IP addresses where IPv6 addresses require brackets around
+    /// them, while for IPv4 they are forbidden.
+    pub IP_BRACKET_REGEX = concatcp!(r"^", IPRE_BRACKET_STR, r"$");
+
+    pub CIDR_V4_REGEX = concatcp!(r"^", CIDR_V4_REGEX_STR, r"$");
+    pub CIDR_V6_REGEX = concatcp!(r"^", CIDR_V6_REGEX_STR, r"$");
+    pub CIDR_REGEX = concatcp!(r"^(?:", CIDR_V4_REGEX_STR, "|",  CIDR_V6_REGEX_STR, r")$");
+
     /// Regex for safe identifiers.
     ///
     /// This
@@ -36,3 +94,29 @@ pub const COMMENT_SCHEMA: Schema = StringSchema::new("Comment.")
     .format(&SINGLE_LINE_COMMENT_FORMAT)
     .max_length(128)
     .schema();
+
+#[test]
+fn test_regexes() {
+    assert!(IP_REGEX.is_match("127.0.0.1"));
+    assert!(IP_V4_REGEX.is_match("127.0.0.1"));
+    assert!(!IP_V6_REGEX.is_match("127.0.0.1"));
+
+    assert!(CIDR_V4_REGEX.is_match("127.0.0.1/24"));
+    assert!(CIDR_REGEX.is_match("127.0.0.1/24"));
+
+    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_V4_REGEX.is_match("2014:b3a:0102:adf1:1234:4321:4afA:BCDF"));
+    assert!(IP_V6_REGEX.is_match("2014:b3a:0102:adf1:1234:4321:4afA:BCDF"));
+
+    assert!(CIDR_V6_REGEX.is_match("2014:b3a:0102:adf1:1234:4321:4afA:BCDF/60"));
+    assert!(CIDR_REGEX.is_match("2014:b3a:0102:adf1:1234:4321:4afA:BCDF/60"));
+
+    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.39.2




^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pbs-devel] [PATCH proxmox 4/4] proxmox-schema: moved common api types from pbs-api-types
  2024-03-15 11:27 [pbs-devel] [PATCH proxmox 1/4] proxmox-schema: use const_format to define static strings Dietmar Maurer
  2024-03-15 11:27 ` [pbs-devel] [PATCH proxmox 2/4] proxmox-auth-api: " Dietmar Maurer
  2024-03-15 11:27 ` [pbs-devel] [PATCH proxmox 3/4] proxmox-schema: add IP address regex/api-types Dietmar Maurer
@ 2024-03-15 11:27 ` Dietmar Maurer
  2024-03-19 10:14 ` [pbs-devel] applied-series: [PATCH proxmox 1/4] proxmox-schema: use const_format to define static strings Wolfgang Bumiller
  3 siblings, 0 replies; 5+ messages in thread
From: Dietmar Maurer @ 2024-03-15 11:27 UTC (permalink / raw)
  To: pbs-devel

We want to use those types in all of our products.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
---
 proxmox-schema/src/api_types.rs | 144 ++++++++++++++++++++++++++++++--
 1 file changed, 139 insertions(+), 5 deletions(-)

diff --git a/proxmox-schema/src/api_types.rs b/proxmox-schema/src/api_types.rs
index 381d4cb..149d389 100644
--- a/proxmox-schema/src/api_types.rs
+++ b/proxmox-schema/src/api_types.rs
@@ -1,7 +1,7 @@
 //! The "basic" api types we generally require along with some of their macros.
 use const_format::concatcp;
 
-use crate::{ApiStringFormat, Schema, StringSchema};
+use crate::{ApiStringFormat, ArraySchema, Schema, StringSchema};
 
 #[rustfmt::skip]
 const IPV4OCTET: &str = r"(?:25[0-5]|(?:2[0-4]|1[0-9]|[1-9])?[0-9])";
@@ -9,14 +9,14 @@ const IPV4OCTET: &str = r"(?:25[0-5]|(?:2[0-4]|1[0-9]|[1-9])?[0-9])";
 #[rustfmt::skip]
 const IPV6H16: &str = r"(?:[0-9a-fA-F]{1,4})";
 
-/// Returns the regular expression string to match IPv4 addresses
+/// Regular expression string to match IPv4 addresses
 #[rustfmt::skip]
 pub const IPV4RE_STR: &str = concatcp!(r"(?:(?:", IPV4OCTET, r"\.){3}", IPV4OCTET, ")");
 
 #[rustfmt::skip]
 const IPV6LS32: &str = concatcp!(r"(?:(?:", IPV4RE_STR, "|", IPV6H16, ":", IPV6H16, "))" );
 
-/// Returns the regular expression string to match IPv6 addresses
+/// Regular expression string to match IPv6 addresses
 #[rustfmt::skip]
 pub const IPV6RE_STR: &str = concatcp!(r"(?:",
     r"(?:(?:",                                         r"(?:", IPV6H16, r":){6})", IPV6LS32, r")|",
@@ -29,7 +29,7 @@ pub const IPV6RE_STR: &str = concatcp!(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)
+/// Regular expression string to match IP addresses (v4 or v6)
 #[rustfmt::skip]
 pub const IPRE_STR: &str = concatcp!(r"(?:", IPV4RE_STR, "|", IPV6RE_STR, ")");
 
@@ -38,14 +38,32 @@ pub const IPRE_STR: &str = concatcp!(r"(?:", IPV4RE_STR, "|", IPV6RE_STR, ")");
 #[rustfmt::skip]
 pub const IPRE_BRACKET_STR: &str = concatcp!(r"(?:", IPV4RE_STR, r"|\[(?:", IPV6RE_STR, r")\]", r")");
 
+/// Regular expression string to match CIDRv4 network
 #[rustfmt::skip]
 pub const CIDR_V4_REGEX_STR: &str = concatcp!(r"(?:", IPV4RE_STR, r"/\d{1,2})$");
 
+/// Regular expression string to match CIDRv6 network
 #[rustfmt::skip]
 pub const CIDR_V6_REGEX_STR: &str = concatcp!(r"(?:", IPV6RE_STR, r"/\d{1,3})$");
 
+/// Regular expression string for safe identifiers.
 #[rustfmt::skip]
-const SAFE_ID_REGEX_STR: &str = r"(?:[A-Za-z0-9_][A-Za-z0-9._\-]*)";
+pub const SAFE_ID_REGEX_STR: &str = r"(?:[A-Za-z0-9_][A-Za-z0-9._\-]*)";
+
+#[rustfmt::skip]
+pub const DNS_LABEL_STR: &str = r"(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?)";
+
+#[rustfmt::skip]
+pub const DNS_NAME_STR: &str = concatcp!(r"(?:(?:", DNS_LABEL_STR, r"\.)*", DNS_LABEL_STR, ")");
+
+#[rustfmt::skip]
+pub const DNS_ALIAS_LABEL_STR: &str = r"(?:[a-zA-Z0-9_](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?)";
+
+#[rustfmt::skip]
+pub const DNS_ALIAS_NAME_STR: &str = concatcp!(r"(?:(?:", DNS_ALIAS_LABEL_STR , r"\.)*", DNS_ALIAS_LABEL_STR, ")");
+
+#[rustfmt::skip]
+pub const PORT_REGEX_STR: &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! {
     /// IPv4 regular expression.
@@ -77,12 +95,72 @@ const_regex! {
     pub PASSWORD_REGEX = r"^[[:^cntrl:]]*$";
     /// Single line comment. Allow everything but control characters.
     pub SINGLE_LINE_COMMENT_REGEX = r"^[[:^cntrl:]]*$";
+    /// Comment spawning multiple lines. Allow everything but control characters.
+    pub MULTI_LINE_COMMENT_REGEX = r"(?m)^([[:^cntrl:]]*)$";
+
+    pub HOSTNAME_REGEX = r"^(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?)$";
+    pub DNS_NAME_REGEX = concatcp!(r"^", DNS_NAME_STR, r"$");
+    pub DNS_ALIAS_REGEX = concatcp!(r"^", DNS_ALIAS_NAME_STR, r"$");
+    pub DNS_NAME_OR_IP_REGEX = concatcp!(r"^(?:", DNS_NAME_STR, "|",  IPRE_STR, r")$");
+    pub HOST_PORT_REGEX = concatcp!(r"^(?:", DNS_NAME_STR, "|", IPRE_BRACKET_STR, "):", PORT_REGEX_STR ,"$");
+    pub HTTP_URL_REGEX = concatcp!(r"^https?://(?:(?:(?:", DNS_NAME_STR, "|", IPRE_BRACKET_STR, ")(?::", PORT_REGEX_STR ,")?)|", IPV6RE_STR,")(?:/[^\x00-\x1F\x7F]*)?$");
+
+    /// Regex to match SHA256 Digest.
+    pub SHA256_HEX_REGEX = r"^[a-f0-9]{64}$";
+
+    pub FINGERPRINT_SHA256_REGEX = r"^(?:[0-9a-fA-F][0-9a-fA-F])(?::[0-9a-fA-F][0-9a-fA-F]){31}$";
+
+    pub UUID_REGEX = r"^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$";
+
+    /// Regex to match systemd date/time format.
+    pub SYSTEMD_DATETIME_REGEX = r"^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}(:\d{2})?)?$";
+
+    /// 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 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 const SAFE_ID_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&SAFE_ID_REGEX);
 pub const PASSWORD_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&PASSWORD_REGEX);
 pub const SINGLE_LINE_COMMENT_FORMAT: ApiStringFormat =
     ApiStringFormat::Pattern(&SINGLE_LINE_COMMENT_REGEX);
+pub const MULTI_LINE_COMMENT_FORMAT: ApiStringFormat =
+    ApiStringFormat::Pattern(&MULTI_LINE_COMMENT_REGEX);
+
+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 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 SYSTEMD_DATETIME_FORMAT: ApiStringFormat =
+    ApiStringFormat::Pattern(&SYSTEMD_DATETIME_REGEX);
+
+pub const HOSTNAME_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&HOSTNAME_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 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 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 PASSWORD_SCHEMA: Schema = StringSchema::new("Password.")
     .format(&PASSWORD_FORMAT)
@@ -95,6 +173,62 @@ pub const COMMENT_SCHEMA: Schema = StringSchema::new("Comment.")
     .max_length(128)
     .schema();
 
+pub const MULTI_LINE_COMMENT_SCHEMA: Schema = StringSchema::new("Comment (multiple lines).")
+    .format(&MULTI_LINE_COMMENT_FORMAT)
+    .schema();
+
+pub const HOSTNAME_SCHEMA: Schema = StringSchema::new("Hostname (as defined in RFC1123).")
+    .format(&HOSTNAME_FORMAT)
+    .schema();
+
+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 SERVICE_ID_SCHEMA: Schema = StringSchema::new("Service ID.").max_length(256).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();
+
 #[test]
 fn test_regexes() {
     assert!(IP_REGEX.is_match("127.0.0.1"));
-- 
2.39.2




^ permalink raw reply	[flat|nested] 5+ messages in thread

* [pbs-devel] applied-series: [PATCH proxmox 1/4] proxmox-schema: use const_format to define static strings.
  2024-03-15 11:27 [pbs-devel] [PATCH proxmox 1/4] proxmox-schema: use const_format to define static strings Dietmar Maurer
                   ` (2 preceding siblings ...)
  2024-03-15 11:27 ` [pbs-devel] [PATCH proxmox 4/4] proxmox-schema: moved common api types from pbs-api-types Dietmar Maurer
@ 2024-03-19 10:14 ` Wolfgang Bumiller
  3 siblings, 0 replies; 5+ messages in thread
From: Wolfgang Bumiller @ 2024-03-19 10:14 UTC (permalink / raw)
  To: Dietmar Maurer; +Cc: pbs-devel

applied series, adapted the notify crate & bumped the 3




^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-03-19 10:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-15 11:27 [pbs-devel] [PATCH proxmox 1/4] proxmox-schema: use const_format to define static strings Dietmar Maurer
2024-03-15 11:27 ` [pbs-devel] [PATCH proxmox 2/4] proxmox-auth-api: " Dietmar Maurer
2024-03-15 11:27 ` [pbs-devel] [PATCH proxmox 3/4] proxmox-schema: add IP address regex/api-types Dietmar Maurer
2024-03-15 11:27 ` [pbs-devel] [PATCH proxmox 4/4] proxmox-schema: moved common api types from pbs-api-types Dietmar Maurer
2024-03-19 10:14 ` [pbs-devel] applied-series: [PATCH proxmox 1/4] proxmox-schema: use const_format to define static strings Wolfgang Bumiller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal