PillarTool/pillar_tool/util/validation.py

84 lines
2.3 KiB
Python

import re
PATH_REGEX = re.compile(r'^[a-zA-Z_-][a-zA-Z0-9_-]*$')
FQDN_REGEX = re.compile(r'^([a-zA-Z0-9.-]+\.)+[a-zA-Z]{2,}$')
ENV_NAME_REGEX = re.compile(r'^[a-zA-Z0-9_-]+$')
STATE_NAME_REGEX = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_-]*(\.[a-zA-Z_][a-zA-Z0-9_-]*)*$')
# TODO: improve doc comment for this function
def validate_environment_name(name: str) -> bool:
"""
Validates an environment name.
Args:
name: The environment name to validate (e.g., "production", "dev_env")
Returns:
True if the name contains only alphanumeric characters, underscores, or dashes.
False otherwise.
Note:
Environment names cannot be empty and must match the pattern [a-zA-Z0-9_-]+
"""
return bool(ENV_NAME_REGEX.match(name))
def validate_state_name(name: str) -> bool:
"""
Validates a state name.
Args:
name: The state name to validate (e.g., "active", "pending_removal")
Returns:
True if the name contains only alphanumeric characters, underscores, or dashes,
and starts with an alphabetic character or underscore.
False otherwise.
Note:
State names cannot be empty and must match the pattern [a-zA-Z_][a-zA-Z0-9_-]*
"""
return bool(STATE_NAME_REGEX.match(name))
def validate_fqdn(fqdn: str) -> bool:
"""
Validates a string against the FQDN regex pattern.
Args:
fqdn: The fully qualified domain name to validate (e.g., "example.com")
Returns:
True if the input matches the FQDN pattern, False otherwise
"""
return re.match(FQDN_REGEX, fqdn) is not None
def split_and_validate_path(path: str) -> list[str] | None:
"""
Splits a path string by slashes, filters out empty fragments, and validates each label.
Args:
path: Input path string in format like "a/b/c" or "/a/b/c"
Returns:
List of validated path labels, or None if validation fails (empty input or invalid characters)
"""
# Split by slashes and filter out empty fragments
labels = list(filter(lambda x: x != "", path.strip().split("/")))
# Return None for empty paths
if len(labels) == 0:
return None
# Validate each label against the PATH_REGEX pattern
for label in labels:
if not re.match(PATH_REGEX, label):
return None
return labels