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
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

use super::super::nodegroup;

/// Status represents a enum with various cluster statuses.
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum Status {
    Active,
    PendingCreate,
    PendingUpdate,
    PendingUpgrade,
    PendingRotateCerts,
    PendingDelete,
    PendingResize,
    PendingNodeReinstall,
    PendingUpgradePatchVersion,
    PendingUpgradeMinorVersion,
    PendingUpdateNodegroup,
    PendingUpgradeMastersConfiguration,
    PendingUpgradeClusterConfiguration,
    Maintenance,
    Error,
    Unknown,
}

impl std::fmt::Display for Status {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match *self {
            Status::Active => "ACTIVE".fmt(f),
            Status::PendingCreate => "PENDING_CREATE".fmt(f),
            Status::PendingUpdate => "PENDING_UPDATE".fmt(f),
            Status::PendingUpgrade => "PENDING_UPGRADE".fmt(f),
            Status::PendingRotateCerts => "PENDING_ROTATE_CERTS".fmt(f),
            Status::PendingDelete => "PENDING_DELETE".fmt(f),
            Status::PendingResize => "PENDING_RESIZE".fmt(f),
            Status::PendingNodeReinstall => "PENDING_NODE_REINSTALL".fmt(f),
            Status::PendingUpgradePatchVersion => "PENDING_UPGRADE_PATCH_VERSION".fmt(f),
            Status::PendingUpgradeMinorVersion => "PENDING_UPGRADE_MINOR_VERSION".fmt(f),
            Status::PendingUpdateNodegroup => "PENDING_UPDATE_NODEGROUP".fmt(f),
            Status::PendingUpgradeMastersConfiguration => {
                "PENDING_UPGRADE_MASTERS_CONFIGURATION".fmt(f)
            }
            Status::PendingUpgradeClusterConfiguration => {
                "PENDING_UPGRADE_CLUSTER_CONFIGURATION".fmt(f)
            }
            Status::Maintenance => "MAINTENANCE".fmt(f),
            Status::Error => "ERROR".fmt(f),
            Status::Unknown => "UNKNOWN".fmt(f),
        }
    }
}

/// Cluster represents a deserialized cluster body from an API response.
#[derive(Debug, Deserialize, Serialize)]
pub struct Cluster {
    /// Cluster identifier.
    pub id: String,

    /// Timestamp in UTC timezone of when the cluster has been created.
    pub created_at: DateTime<Utc>,

    /// Timestamp in UTC timezone of when the cluster has been updated.
    pub updated_at: Option<DateTime<Utc>>,

    /// Cluster name.
    pub name: String,

    /// Cluster status.
    pub status: Status,

    /// Project reference.
    pub project_id: String,

    /// Network reference
    pub network_id: String,

    /// Subnet reference.
    pub subnet_id: String,

    /// IP of the Kubernetes API.
    pub kube_api_ip: String,

    /// Current Kubernetes version of the cluster.
    pub kube_version: String,

    /// Region of where the cluster is located.
    pub region: String,

    /// Timestamp in UTC timezone of when the PKI-tree of the cluster has been updated.
    pub pki_tree_updated_at: Option<DateTime<Utc>>,

    /// UTC time in "hh:mm:ss" format of when the cluster will start its
    /// maintenance tasks.
    pub maintenance_window_start: Option<String>,

    /// UTC time in "hh:mm:ss" format of when the cluster will end its
    /// maintenance tasks.
    pub maintenance_window_end: Option<String>,

    /// Timestamp in UTC timezone of the last cluster maintenance start.
    pub maintenance_last_start: Option<DateTime<Utc>>,

    /// Flag that indicates if worker nodes are allowed to be reinstalled automatically
    /// in case of their unavailability or unhealthiness.
    pub enable_autorepair: bool,

    /// Flag that indicates if Kubernetes patch version of the cluster is allowed to be upgraded
    /// automatically.
    pub enable_patch_version_auto_upgrade: bool,

    /// Flag that indicates that cluster has only a single master and that
    /// control-plane is not in highly available mode.
    pub zonal: bool,

    /// Additional Kubernetes-related options
    /// such as pod security policy, feature gates, etc.
    pub kubernetes_options: KubernetesOptions,
}

/// ClusterRoot represents a root of a deserialized cluster.
#[derive(Debug, Deserialize, Serialize)]
pub struct ClusterRoot {
    pub cluster: Cluster,
}

/// ListRoot represents a root of a list with deserialized clusters.
#[derive(Debug, Deserialize, Serialize)]
pub struct ListRoot {
    pub clusters: Vec<Cluster>,
}

/// KubernetesOptions represents additional Kubernetes-related options
/// such as pod security policy, feature gates, etc.
#[derive(Debug, Deserialize, Serialize)]
pub struct KubernetesOptions {
    /// Flag that indicates if PodSecurityPolicy admission controller
    /// must be turned on or off.
    pub enable_pod_security_policy: bool,
}

/// Create options for a new cluster.
#[derive(Debug, Serialize)]
pub struct CreateOpts {
    name: String,
    network_id: Option<String>,
    subnet_id: Option<String>,
    kube_version: String,
    region: String,
    nodegroups: Option<Vec<nodegroup::schemas::CreateOpts>>,
    maintenance_window_start: Option<String>,
    enable_autorepair: Option<bool>,
    enable_patch_version_auto_upgrade: Option<bool>,
    zonal: Option<bool>,
    kubernetes_options: Option<KubernetesOptions>,
}

impl CreateOpts {
    pub fn new(name: &str, kube_version: &str, region: &str) -> CreateOpts {
        CreateOpts {
            name: String::from(name),
            network_id: None,
            subnet_id: None,
            kube_version: String::from(kube_version),
            region: String::from(region),
            nodegroups: None,
            maintenance_window_start: None,
            enable_autorepair: None,
            enable_patch_version_auto_upgrade: None,
            zonal: None,
            kubernetes_options: None,
        }
    }

    /// Add a reference to a pre-created network.
    pub fn with_network_id(mut self, network_id: &str) -> CreateOpts {
        self.network_id = Some(String::from(network_id));
        self
    }

    /// Add a reference to a pre-created subnet.
    pub fn with_subnet_id(mut self, subnet_id: &str) -> CreateOpts {
        self.subnet_id = Some(String::from(subnet_id));
        self
    }

    /// Add nodegroups parameters.
    pub fn with_nodegroups(
        mut self,
        nodegroups: Vec<nodegroup::schemas::CreateOpts>,
    ) -> CreateOpts {
        self.nodegroups = Some(nodegroups);
        self
    }

    /// Add maintenance_window_start in UTC.
    /// It should be in hh:mm:ss format.
    pub fn with_maintenance_window_start(mut self, maintenance_window_start: &str) -> CreateOpts {
        self.maintenance_window_start = Some(String::from(maintenance_window_start));
        self
    }

    /// Add enable_autorepair flag.
    /// This flag indicates if worker nodes are allowed to be reinstalled automatically
    /// in case of their unavailability or unhealthiness.
    pub fn with_enable_autorepair(mut self, enable_autorepair: bool) -> CreateOpts {
        self.enable_autorepair = Some(enable_autorepair);
        self
    }

    /// Add enable_patch_version_auto_upgrade flag.
    /// This flag indicates if Kubernetes patch version of the cluster is allowed to be upgraded
    /// automatically.
    pub fn with_enable_patch_version_auto_upgrade(
        mut self,
        enable_patch_version_auto_upgrade: bool,
    ) -> CreateOpts {
        self.enable_patch_version_auto_upgrade = Some(enable_patch_version_auto_upgrade);
        self
    }

    /// Add zonal flag.
    /// This flag indicates that cluster has only a single master and that
    /// control-plane is not in highly available mode.
    pub fn with_zonal(mut self, zonal: bool) -> CreateOpts {
        self.zonal = Some(zonal);
        self
    }

    /// Add kubernetes_options.
    /// This parameter represents additional options such as Pod Security Policy,
    /// feature gates, etc.
    pub fn with_kubernetes_options(mut self, kubernetes_options: KubernetesOptions) -> CreateOpts {
        self.kubernetes_options = Some(kubernetes_options);
        self
    }
}

/// CreateOptsRoot represents a root of cluster create options.
#[derive(Debug, Serialize)]
pub struct CreateOptsRoot<'a> {
    pub cluster: &'a CreateOpts,
}