k8s_cluster_api/v1beta1/cluster/
impls.rs

1use std::fmt;
2
3use super::*;
4
5impl Cluster {
6    pub fn with_name(name: &str) -> Self {
7        let spec = ClusterSpec::default();
8        Self::new(name, spec)
9    }
10
11    #[must_use]
12    pub fn set_pod_cidr_block(self, pod_cidr_block: &str) -> Self {
13        let pods = NetworkRanges {
14            cidr_blocks: vec![pod_cidr_block.to_string()],
15        };
16
17        let networks = self.spec.cluster_network.unwrap_or_default();
18        let cluster_networks = ClusterNetwork {
19            pods: Some(pods),
20            ..networks
21        };
22
23        Self {
24            spec: ClusterSpec {
25                cluster_network: Some(cluster_networks),
26                ..self.spec
27            },
28            ..self
29        }
30    }
31
32    // pub fn set_control_plane_ref_name(self, control_plane_ref_name: &str) -> Self {
33    //     let control_plane_ref = ObjectReference {
34    //         api_version: Some(KubeadmControlPlane::api_version(&()).to_string()),
35    //         kind: Some(KubeadmControlPlane::kind(&()).to_string()),
36    //         name: Some(control_plane_ref_name.to_string()),
37    //         ..ObjectReference::default()
38    //     };
39
40    //     Self {
41    //         spec: ClusterSpec {
42    //             control_plane_ref: Some(control_plane_ref),
43    //             ..self.spec
44    //         },
45    //         ..self
46    //     }
47    // }
48
49    #[must_use]
50    pub fn set_control_plane(self, control_plane: &ControlPlane) -> Self {
51        let control_plane_ref = control_plane.object_ref();
52        Self {
53            spec: ClusterSpec {
54                control_plane_ref: Some(control_plane_ref),
55                ..self.spec
56            },
57            ..self
58        }
59    }
60
61    #[must_use]
62    pub fn set_infrastructure(self, infrastructure: &Infrastructure) -> Self {
63        let infrastructure_ref = infrastructure.object_ref();
64        Self {
65            spec: ClusterSpec {
66                infrastructure_ref: Some(infrastructure_ref),
67                ..self.spec
68            },
69            ..self
70        }
71    }
72
73    pub fn infrastructure(&self) -> Option<&corev1::ObjectReference> {
74        self.spec.infrastructure_ref.as_ref()
75    }
76
77    pub fn control_plane(&self) -> Option<&corev1::ObjectReference> {
78        self.spec.control_plane_ref.as_ref()
79    }
80
81    pub fn infrastructure_ready(&self) -> bool {
82        self.status
83            .as_ref()
84            .and_then(|status| status.infrastructure_ready)
85            .unwrap_or_default()
86    }
87
88    pub fn control_plane_ready(&self) -> bool {
89        self.status
90            .as_ref()
91            .and_then(|status| status.control_plane_ready)
92            .unwrap_or_default()
93    }
94
95    pub fn cluster_network(&self) -> Option<&ClusterNetwork> {
96        self.spec.cluster_network.as_ref()
97    }
98
99    pub fn topology(&self) -> Option<&Topology> {
100        self.spec.topology.as_ref()
101    }
102
103    pub fn phase(&self) -> ClusterPhase {
104        self.status
105            .as_ref()
106            .map_or(ClusterPhase::Unknown, |status| status.phase())
107    }
108
109    pub fn conditions(&self) -> Option<&Conditions> {
110        self.status
111            .as_ref()
112            .and_then(|status| status.conditions.as_ref())
113    }
114
115    pub fn conditions_mut(&mut self) -> Option<&mut Conditions> {
116        self.status
117            .as_mut()
118            .and_then(|status| status.conditions.as_mut())
119    }
120
121    pub fn pod_cidrs(&self) -> Option<&[String]> {
122        self.cluster_network()
123            .and_then(|cn| cn.pods.as_ref())
124            .map(|ranges| ranges.cidr_blocks.as_slice())
125    }
126
127    pub fn service_cidrs(&self) -> Option<&[String]> {
128        self.cluster_network()
129            .and_then(|cn| cn.pods.as_ref())
130            .map(|ranges| ranges.cidr_blocks.as_slice())
131    }
132
133    /// GetIPFamily returns a ClusterIPFamily from the configuration provided.
134    pub fn get_ip_family(&self) -> Result<ClusterIpFamily, InvalidIpFamily> {
135        let pod_cidrs = self.pod_cidrs().unwrap_or_default();
136        let service_cidrs = self.service_cidrs().unwrap_or_default();
137
138        if pod_cidrs.is_empty() && service_cidrs.is_empty() {
139            return Ok(ClusterIpFamily::Ipv4IpFamily);
140        }
141
142        let pods_family = ClusterIpFamily::ip_family_for_cidr_strings(pod_cidrs)?;
143        let services_family = ClusterIpFamily::ip_family_for_cidr_strings(service_cidrs)?;
144
145        if pods_family == services_family {
146            Ok(pods_family)
147        } else {
148            Err(InvalidIpFamily::IpFamilyMismatch)
149        }
150    }
151}
152
153impl fmt::Display for NetworkRanges {
154    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155        write!(f, "{}", self.cidr_blocks.join(","))
156    }
157}
158
159impl ClusterStatus {
160    pub fn phase(&self) -> ClusterPhase {
161        self.phase.unwrap_or(ClusterPhase::Unknown)
162    }
163}
164
165impl ApiEndpoint {
166    /// IsZero returns true if both host and port are zero values.
167    pub fn is_zero(&self) -> bool {
168        self.host.is_empty() && self.port == 0
169    }
170
171    /// IsValid returns true if both host and port are non-zero values.
172    pub fn is_valid(&self) -> bool {
173        !self.host.is_empty() && self.port != 0
174    }
175}
176
177impl fmt::Display for ApiEndpoint {
178    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
179        write!(f, "{}:{}", self.host, self.port)
180    }
181}
182
183impl ClusterSpec {
184    pub fn new() -> Self {
185        Self {
186            cluster_network: None,
187            control_plane_ref: None,
188            infrastructure_ref: None,
189            ..Self::default()
190        }
191    }
192}