k8s-cluster-api 0.8.1

Kubernetes Cluster API (CAPI) Rust definitions
Documentation
use kube::CustomResource;

use super::*;

pub use common::*;
pub use condition::*;
pub use ip_family::ClusterIpFamily;
pub use ip_family::InvalidIpFamily;
pub use phase::ClusterPhase;

mod common;
mod condition;
mod impls;
mod ip_family;
mod phase;

/// ClusterFinalizer is the finalizer used by the cluster controller to
/// cleanup the cluster resources when a Cluster is being deleted.
pub const CLUSTER_FINALIZER: &str = "cluster.cluster.x-k8s.io";

/// ClusterSpec defines the desired state of Cluster.
///
#[skip_serializing_none]
#[derive(Clone, Debug, Default, Serialize, Deserialize, CustomResource)]
#[serde(rename_all = "camelCase")]
#[kube(
    group = "cluster.x-k8s.io",
    version = "v1beta1",
    kind = "Cluster",
    plural = "clusters",
    shortname = "cl",
    status = "ClusterStatus"
)]
#[kube(namespaced)]
#[kube(schema = "disabled")]
pub struct ClusterSpec {
    /// Paused can be used to prevent controllers from processing the Cluster and all its associated objects.
    pub paused: Option<bool>,

    /// Cluster network configuration.
    pub cluster_network: Option<ClusterNetwork>,

    /// ControlPlaneEndpoint represents the endpoint used to communicate with the control plane.
    pub control_plane_endpoint: Option<ApiEndpoint>,

    /// ControlPlaneRef is an optional reference to a provider-specific resource that holds
    /// the details for provisioning the Control Plane for a Cluster.
    pub control_plane_ref: Option<corev1::ObjectReference>,

    /// InfrastructureRef is a reference to a provider-specific resource that holds the details
    /// for provisioning infrastructure for a cluster in said provider.
    pub infrastructure_ref: Option<corev1::ObjectReference>,

    /// This encapsulates the topology for the cluster.
    /// NOTE: It is required to enable the ClusterTopology
    /// feature gate flag to activate managed topologies support;
    /// this feature is highly experimental, and parts of it might still be not implemented.
    pub topology: Option<Topology>,
}

/// Topology encapsulates the information of the managed resources.
#[skip_serializing_none]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Topology {
    /// The name of the ClusterClass object to create the topology.
    pub class: String,

    /// The Kubernetes version of the cluster.
    pub version: String,

    /// RolloutAfter performs a rollout of the entire cluster one component at a time,
    /// control plane first and then machine deployments.
    pub rollout_after: Option<metav1::Time>,

    /// ControlPlane describes the cluster control plane.
    pub control_plane: Option<ControlPlaneTopology>,

    /// Workers encapsulates the different constructs that form the worker nodes
    /// for the cluster.
    pub workers: Option<WorkersTopology>,

    /// Variables can be used to customize the Cluster through
    /// patches. They must comply to the corresponding
    /// VariableClasses defined in the ClusterClass.
    pub variables: Option<Vec<ClusterVariable>>,
}

/// ControlPlaneTopology specifies the parameters for the control plane nodes in the cluster.
#[skip_serializing_none]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct ControlPlaneTopology {
    /// Metadata is the metadata applied to the machines of the ControlPlane.
    /// At runtime this metadata is merged with the corresponding metadata from the ClusterClass.
    ///
    /// This field is supported if and only if the control plane provider template
    /// referenced in the ClusterClass is Machine based.
    pub metadata: Option<ObjectMeta>,

    /// Replicas is the number of control plane nodes.
    /// If the value is nil, the ControlPlane object is created without the number of Replicas
    /// and it's assumed that the control plane controller does not implement support for this field.
    /// When specified against a control plane provider that lacks support for this field, this value will be ignored.
    pub replicas: Option<i32>,
}

/// WorkersTopology represents the different sets of worker nodes in the cluster.
#[skip_serializing_none]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct WorkersTopology {
    /// MachineDeployments is a list of machine deployments in the cluster.
    pub machine_deployments: Option<Vec<MachineDeploymentTopology>>,
}

/// MachineDeploymentTopology specifies the different parameters for a set of worker nodes in the topology.
/// This set of nodes is managed by a MachineDeployment object whose lifecycle is managed by the Cluster controller.
#[skip_serializing_none]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct MachineDeploymentTopology {
    /// Metadata is the metadata applied to the machines of the MachineDeployment.
    /// At runtime this metadata is merged with the corresponding metadata from the ClusterClass.
    pub metadata: Option<ObjectMeta>,

    /// Class is the name of the MachineDeploymentClass used to create the set of worker nodes.
    /// This should match one of the deployment classes defined in the ClusterClass object
    /// mentioned in the `Cluster.Spec.Class` field.
    pub class: String,

    /// Name is the unique identifier for this MachineDeploymentTopology.
    /// The value is used with other unique identifiers to create a MachineDeployment's Name
    /// (e.g. cluster's name, etc). In case the name is greater than the allowed maximum length,
    /// the values are hashed together.
    pub name: String,

    /// Replicas is the number of worker nodes belonging to this set.
    /// If the value is nil, the MachineDeployment is created without the number of Replicas (defaulting to zero)
    /// and it's assumed that an external entity (like cluster autoscaler) is responsible for the management
    /// of this value.
    pub replicas: Option<i32>,
}

/// ClusterVariable can be used to customize the Cluster through
/// patches. It must comply to the corresponding
/// ClusterClassVariable defined in the ClusterClass.
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct ClusterVariable {
    /// Name of the variable.
    pub name: String,

    /// Value of the variable.
    /// Note: the value will be validated against the schema of the corresponding ClusterClassVariable
    /// from the ClusterClass.
    /// Note: We have to use apiextensionsv1.JSON instead of a custom JSON type, because controller-tools has a
    /// hard-coded schema for apiextensionsv1.JSON which cannot be produced by another type via controller-tools,
    /// i.e. it's not possible to have no type field.
    /// Ref: https://github.com/kubernetes-sigs/controller-tools/blob/d0e03a142d0ecdd5491593e941ee1d6b5d91dba6/pkg/crd/known_types.go#L106-L111
    pub value: apiextensionsv1::JSON,
}

// ANCHOR_END: ClusterSpec

// ANCHOR: ClusterNetwork

/// ClusterNetwork specifies the different networking
/// parameters for a cluster.
#[skip_serializing_none]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ClusterNetwork {
    /// APIServerPort specifies the port the API Server should bind to.
    /// Defaults to 6443.
    pub api_server_port: Option<i32>,

    /// The network ranges from which service VIPs are allocated.
    pub services: Option<NetworkRanges>,

    /// The network ranges from which Pod networks are allocated.
    pub pods: Option<NetworkRanges>,

    /// Domain name for services.
    pub service_domain: Option<String>,
}

// ANCHOR_END: ClusterNetwork

// ANCHOR: NetworkRanges

/// NetworkRanges represents ranges of network addresses.
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct NetworkRanges {
    pub cidr_blocks: Vec<String>,
}

// ANCHOR_END: NetworkRanges

// ANCHOR: ClusterStatus

/// ClusterStatus defines the observed state of Cluster.
#[skip_serializing_none]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ClusterStatus {
    /// FailureDomains is a slice of failure domain objects synced from the infrastructure provider.
    pub failure_domains: Option<FailureDomains>,

    /// FailureReason indicates that there is a fatal problem reconciling the
    /// state, and will be set to a token value suitable for
    /// programmatic interpretation.
    pub failure_reason: Option<capierrors::ClusterStatusError>,

    /// FailureMessage indicates that there is a fatal problem reconciling the
    /// state, and will be set to a descriptive error message.
    pub failure_message: Option<String>,

    /// Phase represents the current phase of cluster actuation.
    /// E.g. Pending, Running, Terminating, Failed etc.
    pub phase: Option<ClusterPhase>,

    /// InfrastructureReady is the state of the infrastructure provider.
    // +optional
    pub infrastructure_ready: Option<bool>,

    /// ControlPlaneReady defines if the control plane is ready.
    // +optional
    pub control_plane_ready: Option<bool>,

    /// Conditions defines current service state of the cluster.
    // +optional
    pub conditions: Option<Conditions>,

    /// ObservedGeneration is the latest generation observed by the controller.
    // +optional
    pub observed_generation: i64,
}

// ANCHOR_END: ClusterStatus

// ANCHOR: APIEndpoint

/// APIEndpoint represents a reachable Kubernetes API endpoint.
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct ApiEndpoint {
    /// The hostname on which the API server is serving.
    pub host: String,

    /// The port on which the API server is serving.
    pub port: i32,
}

// ANCHOR_END: APIEndpoint

/* ############

// +kubebuilder:object:root=true
// +kubebuilder:resource:path=clusters,shortName=cl,scope=Namespaced,categories=cluster-api
// +kubebuilder:storageversion
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase",description="Cluster status such as Pending/Provisioning/Provisioned/Deleting/Failed"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Time duration since creation of Cluster"
// +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".spec.topology.version",description="Kubernetes version associated with this Cluster"



// +kubebuilder:object:root=true

// ClusterList contains a list of Cluster.
type ClusterList struct {
    metav1.TypeMeta `json:",inline"`
    metav1.ListMeta `json:"metadata,omitempty"`
    Items           []Cluster `json:"items"`
}

func init() {
    SchemeBuilder.Register(&Cluster{}, &ClusterList{})
}

############ */

/// FailureDomains is a slice of FailureDomains.
pub type FailureDomains = BTreeMap<String, FailureDomainSpec>;

/* ############
// FilterControlPlane returns a FailureDomain slice containing only the domains suitable to be used
// for control plane nodes.
func (in FailureDomains) FilterControlPlane() FailureDomains {
    res := make(FailureDomains)
    for id, spec := range in {
        if spec.ControlPlane {
            res[id] = spec
        }
    }
    return res
}

// GetIDs returns a slice containing the ids for failure domains.
func (in FailureDomains) GetIDs() []*string {
    ids := make([]*string, 0, len(in))
    for id := range in {
        ids = append(ids, pointer.StringPtr(id))
    }
    return ids
}

############ */

/// FailureDomainSpec is the Schema for Cluster API failure domains.
/// It allows controllers to understand how many failure domains a cluster can optionally span across.
#[skip_serializing_none]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct FailureDomainSpec {
    /// ControlPlane determines if this failure domain is suitable for use by control plane machines.
    pub control_plane: Option<bool>,

    /// Attributes is a free form map of attributes an infrastructure provider might use or require.
    pub attributes: Option<BTreeMap<String, String>>,
}

#[cfg(test)]
mod tests;