platz_sdk/resources/
deployment_tasks.rs

1use crate::client::{Paginated, PlatzClient};
2use anyhow::Result;
3use chrono::prelude::*;
4use kv_derive::{prelude::*, IntoVec};
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7use std::collections::HashMap;
8use uuid::Uuid;
9
10#[derive(Debug, Deserialize, Clone)]
11pub enum DeploymentTaskStatus {
12    Pending,
13    Started,
14    Failed,
15    Canceled,
16    Done,
17}
18
19pub type JsonDiff = HashMap<String, (Value, Value)>;
20#[derive(Default, IntoVec)]
21pub struct DeploymentTaskFilters {
22    #[kv(optional)]
23    pub cluster_id: Option<Uuid>,
24    #[kv(optional)]
25    pub deployment_id: Option<Uuid>,
26    #[kv(optional)]
27    pub active_only: Option<bool>,
28    #[kv(optional)]
29    pub show_future: Option<bool>,
30    #[kv(optional)]
31    pub created_from: Option<DateTime<Utc>>,
32}
33
34#[derive(Debug, Serialize)]
35pub struct ApiNewDeploymentTask {
36    pub deployment_id: Uuid,
37    pub operation: DeploymentTaskOperation,
38    pub execute_at: Option<DateTime<Utc>>,
39}
40
41#[derive(Debug, Deserialize, Clone)]
42pub struct DeploymentTask {
43    pub id: Uuid,
44    pub created_at: DateTime<Utc>,
45    pub execute_at: DateTime<Utc>,
46    pub first_attempted_at: Option<DateTime<Utc>>,
47    pub started_at: Option<DateTime<Utc>>,
48    pub finished_at: Option<DateTime<Utc>>,
49    pub cluster_id: Uuid,
50    pub deployment_id: Uuid,
51    pub acting_user_id: Option<Uuid>,
52    pub acting_deployment_id: Option<Uuid>,
53    pub operation: DeploymentTaskOperation,
54    pub status: DeploymentTaskStatus,
55    pub reason: Option<String>,
56    pub canceled_by_user_id: Option<Uuid>,
57    pub canceled_by_deployment_id: Option<Uuid>,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize)]
61pub enum DeploymentTaskOperation {
62    Install(DeploymentInstallTask),
63    Upgrade(DeploymentUpgradeTask),
64    Reinstall(DeploymentReinstallTask),
65    Recreate(DeploymentRecreaseTask),
66    Uninstall(DeploymentUninstallTask),
67    InvokeAction(DeploymentInvokeActionTask),
68    RestartK8sResource(DeploymentRestartK8sResourceTask),
69}
70
71impl DeploymentTaskOperation {
72    pub fn get_type_name(&self) -> String {
73        match self {
74            Self::Install(_) => "Install".into(),
75            Self::Upgrade(_) => "Upgrade".into(),
76            Self::Reinstall(_) => "Reinstall".into(),
77            Self::Recreate(_) => "Recreate".into(),
78            Self::Uninstall(_) => "Uninstall".into(),
79            Self::InvokeAction(x) => format!("Invoke Action {}", x.action_id),
80            Self::RestartK8sResource(_) => "Restart K8s Resource".into(),
81        }
82    }
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct DeploymentInstallTask {
87    pub helm_chart_id: Uuid,
88    pub config_inputs: serde_json::Value,
89    pub values_override: Option<serde_json::Value>,
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
93pub struct DeploymentUpgradeTask {
94    pub helm_chart_id: Uuid,
95    pub prev_helm_chart_id: Option<Uuid>,
96    pub config_inputs: serde_json::Value,
97    pub config_delta: Option<JsonDiff>,
98    pub values_override: Option<serde_json::Value>,
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
102pub struct DeploymentReinstallTask {
103    pub reason: String,
104}
105#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct DeploymentRecreaseTask {
107    pub old_cluster_id: Uuid,
108    pub old_namespace: String,
109    pub new_cluster_id: Uuid,
110    pub new_namespace: String,
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize)]
114pub struct DeploymentUninstallTask {}
115
116#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct DeploymentInvokeActionTask {
118    pub helm_chart_id: Uuid,
119    pub action_id: String,
120    pub body: serde_json::Value,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
124pub struct DeploymentRestartK8sResourceTask {
125    pub resource_id: Uuid,
126    pub resource_name: String,
127}
128
129#[derive(Debug, Clone, Serialize, Deserialize)]
130pub struct CancelDeploymentTask {
131    pub reason: Option<String>,
132}
133
134impl PlatzClient {
135    pub async fn deployment_tasks(
136        &self,
137        filters: DeploymentTaskFilters,
138    ) -> Result<Vec<DeploymentTask>> {
139        Ok(self
140            .request(reqwest::Method::GET, "/api/v2/deployment-tasks")
141            .add_to_query(filters.into_vec())
142            .paginated()
143            .await?)
144    }
145
146    pub async fn deployment_task(&self, deployment_task_id: Uuid) -> Result<DeploymentTask> {
147        Ok(self
148            .request(
149                reqwest::Method::GET,
150                format!("/api/v2/deployment-tasks/{deployment_task_id}"),
151            )
152            .send()
153            .await?)
154    }
155
156    pub async fn last_deployment_task(&self, deployment_id: Uuid) -> Result<DeploymentTask> {
157        let single_page_tasks: Paginated<DeploymentTask> = self
158            .request(reqwest::Method::GET, "/api/v2/deployment-tasks")
159            .add_to_query(
160                DeploymentTaskFilters {
161                    deployment_id: Some(deployment_id),
162                    ..DeploymentTaskFilters::default()
163                }
164                .into_vec(),
165            )
166            .single_page(1, Some(1))
167            .await?;
168        Ok(single_page_tasks.items.first().unwrap().to_owned())
169    }
170
171    pub async fn cancel_deployment_task(
172        &self,
173        deployment_task_id: Uuid,
174        info: CancelDeploymentTask,
175    ) -> Result<DeploymentTask> {
176        Ok(self
177            .request(
178                reqwest::Method::DELETE,
179                format!("/api/v2/deployment-tasks/{deployment_task_id}"),
180            )
181            .send_with_body(info)
182            .await?)
183    }
184
185    pub async fn create_deployment_task(
186        &self,
187        new_task: ApiNewDeploymentTask,
188    ) -> Result<DeploymentTask> {
189        Ok(self
190            .request(reqwest::Method::POST, "/api/v2/deployment-tasks")
191            .send_with_body(new_task)
192            .await?)
193    }
194}