fix: added K8sName type for strict naming of Kubernetes resources
This commit is contained in:
parent
759a9287d3
commit
90b89224d8
96
harmony_types/src/k8s_name.rs
Normal file
96
harmony_types/src/k8s_name.rs
Normal file
@ -0,0 +1,96 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct K8sName(pub String);
|
||||
|
||||
impl K8sName {
|
||||
#[cfg(test)]
|
||||
pub fn dummy() -> Self {
|
||||
K8sName("example".to_string())
|
||||
}
|
||||
|
||||
fn is_valid(name: &str) -> bool {
|
||||
if name.is_empty() || name.len() > 63 {
|
||||
return false;
|
||||
}
|
||||
|
||||
let b = name.as_bytes();
|
||||
|
||||
if !b[0].is_ascii_alphanumeric() || !b[b.len() - 1].is_ascii_alphanumeric() {
|
||||
return false;
|
||||
}
|
||||
|
||||
b.iter()
|
||||
.all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || *c == b'-')
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for K8sName {
|
||||
type Err = K8sNameError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if !Self::is_valid(s) {
|
||||
return Err(K8sNameError::InvalidFormat(format!(
|
||||
"Invalid Kubernetes resource name '{s}': \
|
||||
must match DNS-1123 (lowercase alphanumeric, hyphens, <=63 chars)"
|
||||
)));
|
||||
};
|
||||
|
||||
Ok(K8sName(s.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum K8sNameError {
|
||||
InvalidFormat(String),
|
||||
}
|
||||
|
||||
impl From<&K8sName> for String {
|
||||
fn from(value: &K8sName) -> Self {
|
||||
value.0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for K8sName {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_valid_name() {
|
||||
assert!(K8sName::from_str("k8s-name-test").is_ok());
|
||||
assert!(K8sName::from_str("n").is_ok());
|
||||
assert!(K8sName::from_str("node1").is_ok());
|
||||
assert!(K8sName::from_str("my-app-v2").is_ok());
|
||||
assert!(K8sName::from_str("service123").is_ok());
|
||||
assert!(K8sName::from_str("abcdefghijklmnopqrstuvwxyz-1234567890").is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_name() {
|
||||
assert!(K8sName::from_str("").is_err());
|
||||
assert!(K8sName::from_str(".config").is_err());
|
||||
assert!(K8sName::from_str("_hidden").is_err());
|
||||
assert!(K8sName::from_str("UPPER-CASE").is_err());
|
||||
assert!(K8sName::from_str("123-$$$").is_err());
|
||||
assert!(K8sName::from_str("app!name").is_err());
|
||||
assert!(K8sName::from_str("my..app").is_err());
|
||||
assert!(K8sName::from_str("backend-").is_err());
|
||||
assert!(K8sName::from_str("-frontend").is_err());
|
||||
assert!(K8sName::from_str("InvalidName").is_err());
|
||||
assert!(
|
||||
K8sName::from_str("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
|
||||
.is_err()
|
||||
);
|
||||
assert!(K8sName::from_str("k8s name").is_err());
|
||||
assert!(K8sName::from_str("k8s_name").is_err());
|
||||
assert!(K8sName::from_str("k8s@name").is_err());
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
pub mod id;
|
||||
pub mod k8s_name;
|
||||
pub mod net;
|
||||
pub mod switch;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user