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