mirror of
https://git.proxmox.com/git/proxmox
synced 2025-08-04 17:14:54 +00:00
proxmox-schema: add IP address regex/api-types
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
This commit is contained in:
parent
a6f1b36fa6
commit
d74fa06253
@ -3,10 +3,68 @@ use const_format::concatcp;
|
|||||||
|
|
||||||
use crate::{ApiStringFormat, Schema, StringSchema};
|
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]
|
#[rustfmt::skip]
|
||||||
const SAFE_ID_REGEX_STR: &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! {
|
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.
|
/// Regex for safe identifiers.
|
||||||
///
|
///
|
||||||
/// This
|
/// This
|
||||||
@ -36,3 +94,29 @@ pub const COMMENT_SCHEMA: Schema = StringSchema::new("Comment.")
|
|||||||
.format(&SINGLE_LINE_COMMENT_FORMAT)
|
.format(&SINGLE_LINE_COMMENT_FORMAT)
|
||||||
.max_length(128)
|
.max_length(128)
|
||||||
.schema();
|
.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]"));
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user