k8s-cluster-api 0.8.1

Kubernetes Cluster API (CAPI) Rust definitions
Documentation
use std::fmt;

use super::*;

impl Cluster {
    pub fn with_name(name: &str) -> Self {
        let spec = ClusterSpec::default();
        Self::new(name, spec)
    }

    #[must_use]
    pub fn set_pod_cidr_block(self, pod_cidr_block: &str) -> Self {
        let pods = NetworkRanges {
            cidr_blocks: vec![pod_cidr_block.to_string()],
        };

        let networks = self.spec.cluster_network.unwrap_or_default();
        let cluster_networks = ClusterNetwork {
            pods: Some(pods),
            ..networks
        };

        Self {
            spec: ClusterSpec {
                cluster_network: Some(cluster_networks),
                ..self.spec
            },
            ..self
        }
    }

    // pub fn set_control_plane_ref_name(self, control_plane_ref_name: &str) -> Self {
    //     let control_plane_ref = ObjectReference {
    //         api_version: Some(KubeadmControlPlane::api_version(&()).to_string()),
    //         kind: Some(KubeadmControlPlane::kind(&()).to_string()),
    //         name: Some(control_plane_ref_name.to_string()),
    //         ..ObjectReference::default()
    //     };

    //     Self {
    //         spec: ClusterSpec {
    //             control_plane_ref: Some(control_plane_ref),
    //             ..self.spec
    //         },
    //         ..self
    //     }
    // }

    #[must_use]
    pub fn set_control_plane(self, control_plane: &ControlPlane) -> Self {
        let control_plane_ref = control_plane.object_ref();
        Self {
            spec: ClusterSpec {
                control_plane_ref: Some(control_plane_ref),
                ..self.spec
            },
            ..self
        }
    }

    #[must_use]
    pub fn set_infrastructure(self, infrastructure: &Infrastructure) -> Self {
        let infrastructure_ref = infrastructure.object_ref();
        Self {
            spec: ClusterSpec {
                infrastructure_ref: Some(infrastructure_ref),
                ..self.spec
            },
            ..self
        }
    }

    pub fn infrastructure(&self) -> Option<&corev1::ObjectReference> {
        self.spec.infrastructure_ref.as_ref()
    }

    pub fn control_plane(&self) -> Option<&corev1::ObjectReference> {
        self.spec.control_plane_ref.as_ref()
    }

    pub fn infrastructure_ready(&self) -> bool {
        self.status
            .as_ref()
            .and_then(|status| status.infrastructure_ready)
            .unwrap_or_default()
    }

    pub fn control_plane_ready(&self) -> bool {
        self.status
            .as_ref()
            .and_then(|status| status.control_plane_ready)
            .unwrap_or_default()
    }

    pub fn cluster_network(&self) -> Option<&ClusterNetwork> {
        self.spec.cluster_network.as_ref()
    }

    pub fn topology(&self) -> Option<&Topology> {
        self.spec.topology.as_ref()
    }

    pub fn phase(&self) -> ClusterPhase {
        self.status
            .as_ref()
            .map_or(ClusterPhase::Unknown, |status| status.phase())
    }

    pub fn conditions(&self) -> Option<&Conditions> {
        self.status
            .as_ref()
            .and_then(|status| status.conditions.as_ref())
    }

    pub fn conditions_mut(&mut self) -> Option<&mut Conditions> {
        self.status
            .as_mut()
            .and_then(|status| status.conditions.as_mut())
    }

    pub fn pod_cidrs(&self) -> Option<&[String]> {
        self.cluster_network()
            .and_then(|cn| cn.pods.as_ref())
            .map(|ranges| ranges.cidr_blocks.as_slice())
    }

    pub fn service_cidrs(&self) -> Option<&[String]> {
        self.cluster_network()
            .and_then(|cn| cn.pods.as_ref())
            .map(|ranges| ranges.cidr_blocks.as_slice())
    }

    /// GetIPFamily returns a ClusterIPFamily from the configuration provided.
    pub fn get_ip_family(&self) -> Result<ClusterIpFamily, InvalidIpFamily> {
        let pod_cidrs = self.pod_cidrs().unwrap_or_default();
        let service_cidrs = self.service_cidrs().unwrap_or_default();

        if pod_cidrs.is_empty() && service_cidrs.is_empty() {
            return Ok(ClusterIpFamily::Ipv4IpFamily);
        }

        let pods_family = ClusterIpFamily::ip_family_for_cidr_strings(pod_cidrs)?;
        let services_family = ClusterIpFamily::ip_family_for_cidr_strings(service_cidrs)?;

        if pods_family == services_family {
            Ok(pods_family)
        } else {
            Err(InvalidIpFamily::IpFamilyMismatch)
        }
    }
}

impl fmt::Display for NetworkRanges {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.cidr_blocks.join(","))
    }
}

impl ClusterStatus {
    pub fn phase(&self) -> ClusterPhase {
        self.phase.unwrap_or(ClusterPhase::Unknown)
    }
}

impl ApiEndpoint {
    /// IsZero returns true if both host and port are zero values.
    pub fn is_zero(&self) -> bool {
        self.host.is_empty() && self.port == 0
    }

    /// IsValid returns true if both host and port are non-zero values.
    pub fn is_valid(&self) -> bool {
        !self.host.is_empty() && self.port != 0
    }
}

impl fmt::Display for ApiEndpoint {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}:{}", self.host, self.port)
    }
}

impl ClusterSpec {
    pub fn new() -> Self {
        Self {
            cluster_network: None,
            control_plane_ref: None,
            infrastructure_ref: None,
            ..Self::default()
        }
    }
}