platz_chart_ext/actions/
v0.rs1use crate::collection::UiSchemaCollections;
2use crate::error::UiSchemaInputError;
3use crate::ui_schema::UiSchema;
4use serde::{Deserialize, Serialize};
5use url::Url;
6use uuid::Uuid;
7
8#[derive(Clone, Debug, Deserialize, Serialize)]
9#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
10pub struct ChartExtActionsV0 {
11 pub schema_version: u64,
12 pub actions: Vec<ChartExtActionV0>,
13}
14
15impl ChartExtActionsV0 {
16 pub fn find(&self, action_id: &str) -> Option<&ChartExtActionV0> {
17 self.actions.iter().find(|action| action.id == action_id)
18 }
19
20 pub fn get_actions(&self) -> Vec<ChartExtActionV0> {
21 self.actions.to_vec()
22 }
23}
24
25#[derive(Clone, Debug, Copy, PartialEq, Eq, Serialize, Deserialize)]
26#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
27pub enum ChartExtActionUserDeploymentRole {
28 Owner,
29 Maintainer,
30}
31
32#[derive(Clone, Debug, Deserialize, Serialize)]
33#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
34pub enum ChartExtActionEndpoint {
35 #[serde(rename = "standard_ingress")]
36 StandardIngress,
37}
38
39#[derive(Clone, Debug, Deserialize, Serialize)]
40#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
41#[serde(rename_all = "UPPERCASE")]
42pub enum ChartExtActionMethod {
43 Get,
44 Post,
45 Put,
46 Patch,
47 Delete,
48}
49
50#[derive(Clone, Debug, Deserialize, Serialize)]
51#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
52pub struct ChartExtActionTarget {
53 pub endpoint: ChartExtActionEndpoint,
54 pub path: String,
55 pub method: ChartExtActionMethod,
56}
57
58impl ChartExtActionTarget {
59 pub async fn call<R, T, E>(&self, resolver: &R, body: T) -> Result<String, E>
60 where
61 R: ChartExtActionTargetResolver,
62 T: Serialize,
63 E: From<R::Error> + From<reqwest::Error>,
64 {
65 let url = resolver.resolve(self).await?;
66 let method = match self.method {
67 ChartExtActionMethod::Get => reqwest::Method::GET,
68 ChartExtActionMethod::Post => reqwest::Method::POST,
69 ChartExtActionMethod::Put => reqwest::Method::PUT,
70 ChartExtActionMethod::Patch => reqwest::Method::PATCH,
71 ChartExtActionMethod::Delete => reqwest::Method::DELETE,
72 };
73
74 Ok(reqwest::Client::new()
75 .request(method, url)
76 .json(&body)
77 .send()
78 .await?
79 .error_for_status()?
80 .text()
81 .await?)
82 }
83}
84
85pub trait ChartExtActionTargetResolver {
86 type Error;
87
88 #[allow(async_fn_in_trait)]
89 async fn resolve(&self, target: &ChartExtActionTarget) -> Result<Url, Self::Error>;
90}
91
92#[derive(Clone, Debug, Deserialize, Serialize)]
93#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
94pub struct ChartExtActionV0 {
95 pub id: String,
96 pub allowed_role: ChartExtActionUserDeploymentRole,
97 #[serde(default)]
98 pub allowed_on_statuses: Vec<String>,
99 #[serde(flatten)]
100 pub target: ChartExtActionTarget,
101 pub title: String,
102 pub fontawesome_icon: Option<String>,
103 pub description: String,
104 #[serde(default)]
105 pub dangerous: bool,
106 pub ui_schema: Option<UiSchema>,
107}
108
109impl ChartExtActionV0 {
110 pub async fn generate_body<C>(
111 &self,
112 env_id: Uuid,
113 inputs: serde_json::Value,
114 ) -> Result<serde_json::Value, UiSchemaInputError<C::Error>>
115 where
116 C: UiSchemaCollections,
117 {
118 let ui_schema = match self.ui_schema.as_ref() {
119 None => return Ok(inputs),
120 Some(ui_schema) => ui_schema,
121 };
122 Ok(ui_schema.get_values::<C>(env_id, &inputs).await?.into())
123 }
124}