1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use std::fmt;
use ipnet::IpNet;
use thiserror::Error;
use super::*;
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
pub enum ClusterIpFamily {
InvalidIpFamily,
Ipv4IpFamily,
Ipv6IpFamily,
DualStackIpFamily,
}
impl Default for ClusterIpFamily {
fn default() -> Self {
Self::InvalidIpFamily
}
}
impl ClusterIpFamily {
pub fn to_str(&self) -> &'static str {
match self {
Self::InvalidIpFamily => "InvalidIPFamily",
Self::Ipv4IpFamily => "IPv4IPFamily",
Self::Ipv6IpFamily => "IPv6IPFamily",
Self::DualStackIpFamily => "DualStackIPFamily",
}
}
pub(crate) fn ip_family_for_cidr_strings(cidrs: &[String]) -> Result<Self, InvalidIpFamily> {
let count = cidrs.len();
if count > 2 {
return Err(InvalidIpFamily::TooManyCidrs(count));
}
let families = cidrs
.iter()
.map(|text| text.parse())
.collect::<Result<Vec<IpNet>, _>>()?
.into();
Ok(families)
}
}
impl From<IpNet> for ClusterIpFamily {
fn from(ipnet: IpNet) -> Self {
match ipnet {
IpNet::V4(_) => Self::Ipv4IpFamily,
IpNet::V6(_) => Self::Ipv6IpFamily,
}
}
}
impl From<Vec<IpNet>> for ClusterIpFamily {
fn from(nets: Vec<IpNet>) -> Self {
let mut nets = nets.into_iter().map(Self::from);
let first = nets.next();
let second = nets.next();
if let Some(first) = first {
if let Some(second) = second {
if first == second {
first
} else {
Self::DualStackIpFamily
}
} else {
first
}
} else {
Self::Ipv4IpFamily
}
}
}
impl fmt::Display for ClusterIpFamily {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.to_str().fmt(f)
}
}
#[derive(Debug, Error)]
pub enum InvalidIpFamily {
#[error("Too many ({0}) CIDRs specified")]
TooManyCidrs(usize),
#[error("Could not parse CIDR: {0}")]
InvalidCidr(#[from] ipnet::AddrParseError),
#[error("Pods and Services IP Families mismatch")]
IpFamilyMismatch,
}