k8s_cluster_api/v1beta1/cluster/
ip_family.rs

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