clevercloud_sdk/v4/addon_provider/
mod.rs

1//! # Addon provider module
2//!
3//! This module provide structures and helpers to interact with clever-cloud's
4//! addon-provider
5
6use std::{
7    collections::BTreeMap,
8    convert::TryFrom,
9    fmt::{self, Debug, Display, Formatter},
10    hash::Hash,
11    str::FromStr,
12};
13
14#[cfg(feature = "jsonschemas")]
15use schemars::JsonSchema;
16use serde::{Deserialize, Serialize};
17
18pub mod config_provider;
19pub mod elasticsearch;
20pub mod mongodb;
21pub mod mysql;
22pub mod postgresql;
23pub mod redis;
24
25// -----------------------------------------------------------------------------
26// Feature structure
27
28#[cfg_attr(feature = "jsonschemas", derive(JsonSchema))]
29#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Clone, Debug)]
30pub struct Feature {
31    #[serde(rename = "name")]
32    pub name: String,
33    #[serde(rename = "enabled")]
34    pub enabled: bool,
35}
36
37// -----------------------------------------------------------------------------
38// Cluster structure
39
40#[cfg_attr(feature = "jsonschemas", derive(JsonSchema))]
41#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
42pub struct Cluster<T> {
43    #[serde(rename = "id")]
44    pub id: String,
45    #[serde(rename = "label")]
46    pub label: String,
47    #[serde(rename = "zone")]
48    pub zone: String,
49    #[serde(rename = "features")]
50    pub features: Vec<Feature>,
51    #[serde(rename = "version")]
52    pub version: T,
53}
54
55// -----------------------------------------------------------------------------
56// AddonProvider structure
57
58#[cfg_attr(feature = "jsonschemas", derive(JsonSchema))]
59#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
60pub struct AddonProvider<T>
61where
62    T: Ord,
63{
64    #[serde(rename = "providerId")]
65    pub provider_id: AddonProviderId,
66    #[serde(rename = "clusters")]
67    pub clusters: Vec<Cluster<T>>,
68    #[serde(rename = "dedicated")]
69    pub dedicated: BTreeMap<T, Vec<Feature>>,
70    #[serde(rename = "defaultDedicatedVersion")]
71    pub default: T,
72}
73
74// -----------------------------------------------------------------------------
75// Error enumeration
76
77#[derive(thiserror::Error, Debug)]
78pub enum Error {
79    #[error(
80        "failed to parse addon provider identifier '{0}', available options are \
81        'postgresql-addon', 'redis-addon', 'mysql-addon', 'mongodb-addon', \
82        'addon-pulsar', 'config-provider', 'es-addon', 'kv', 'metabase', 'keycloak', \
83        'cellar-addon', 'addon-matomo', 'addon-otoroshi' and 'azimutt'"
84    )]
85    Parse(String),
86}
87
88// -----------------------------------------------------------------------------
89// AddonProviderName structure
90
91#[cfg_attr(feature = "jsonschemas", derive(JsonSchema))]
92#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)]
93#[serde(untagged, try_from = "String", into = "String")]
94pub enum AddonProviderId {
95    PostgreSql,
96    Redis,
97    MySql,
98    MongoDb,
99    Pulsar,
100    KV,
101    ConfigProvider,
102    ElasticSearch,
103    Metabase,
104    Keycloak,
105    Cellar,
106    Matomo,
107    Otoroshi,
108    Azimutt,
109}
110
111impl AddonProviderId {
112    pub const fn as_str(&self) -> &'static str {
113        match self {
114            Self::PostgreSql => "postgresql-addon",
115            Self::Redis => "redis-addon",
116            Self::MySql => "mysql-addon",
117            Self::MongoDb => "mongodb-addon",
118            Self::Pulsar => "addon-pulsar",
119            Self::KV => "kv",
120            Self::ConfigProvider => "config-provider",
121            Self::ElasticSearch => "es-addon",
122            Self::Metabase => "metabase",
123            Self::Keycloak => "keycloak",
124            Self::Cellar => "cellar-addon",
125            Self::Matomo => "addon-matomo",
126            Self::Otoroshi => "otoroshi",
127            Self::Azimutt => "azimutt",
128        }
129    }
130}
131
132impl FromStr for AddonProviderId {
133    type Err = Error;
134
135    #[cfg_attr(feature = "tracing", tracing::instrument)]
136    fn from_str(s: &str) -> Result<Self, Self::Err> {
137        Ok(match s.to_lowercase().as_str() {
138            "postgresql-addon" => Self::PostgreSql,
139            "redis-addon" => Self::Redis,
140            "mysql-addon" => Self::MySql,
141            "mongodb-addon" => Self::MongoDb,
142            "addon-pulsar" => Self::Pulsar,
143            "kv" => Self::KV,
144            "config-provider" => Self::ConfigProvider,
145            "es-addon" => Self::ElasticSearch,
146            "metabase" => Self::Metabase,
147            "cellar-addon" => Self::Cellar,
148            "keycloak" => Self::Keycloak,
149            "addon-matomo" => Self::Matomo,
150            "otoroshi" => Self::Otoroshi,
151            "azimutt" => Self::Azimutt,
152            _ => return Err(Error::Parse(s.to_owned())),
153        })
154    }
155}
156
157impl TryFrom<String> for AddonProviderId {
158    type Error = Error;
159
160    #[cfg_attr(feature = "tracing", tracing::instrument)]
161    fn try_from(s: String) -> Result<Self, Self::Error> {
162        Self::from_str(&s)
163    }
164}
165
166#[allow(clippy::from_over_into)]
167impl Into<String> for AddonProviderId {
168    #[cfg_attr(feature = "tracing", tracing::instrument)]
169    fn into(self) -> String {
170        self.to_string()
171    }
172}
173
174impl Display for AddonProviderId {
175    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
176        fmt::Display::fmt(self.as_str(), f)
177    }
178}