cdl_openapi/model_storage/
object.rs1use std::net::Ipv4Addr;
2
3use cdl_k8s_core::openapi::Url;
4use k8s_openapi::{
5 api::core::v1::ResourceRequirements, apimachinery::pkg::api::resource::Quantity,
6};
7use maplit::btreemap;
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10
11use crate::model_user::ModelUserAccessTokenSecretRefSpec;
12
13#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
14#[serde(rename_all = "camelCase")]
15pub enum ModelStorageObjectSpec {
16 Borrowed(ModelStorageObjectBorrowedSpec),
17 Cloned(ModelStorageObjectClonedSpec),
18 Owned(#[serde(default)] ModelStorageObjectOwnedSpec),
19}
20
21impl Default for ModelStorageObjectSpec {
22 fn default() -> Self {
23 Self::Owned(Default::default())
24 }
25}
26
27impl ModelStorageObjectSpec {
28 #[inline]
29 pub(super) fn endpoint(&self, namespace: &str) -> Option<Url> {
30 match self {
31 Self::Borrowed(spec) => spec.endpoint(),
32 Self::Cloned(spec) => spec.endpoint(namespace),
33 Self::Owned(spec) => spec.endpoint(namespace),
34 }
35 }
36
37 pub(super) const fn is_unique(&self) -> bool {
38 match self {
39 Self::Borrowed(_) => false,
40 Self::Cloned(_) => true,
41 Self::Owned(_) => true,
42 }
43 }
44}
45
46#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
47#[serde(rename_all = "camelCase")]
48pub struct ModelStorageObjectBorrowedSpec {
49 #[serde(default, flatten)]
50 pub reference: ModelStorageObjectRefSpec,
51}
52
53impl ModelStorageObjectBorrowedSpec {
54 #[inline]
55 fn endpoint(&self) -> Option<Url> {
56 self.reference.endpoint()
57 }
58}
59
60#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
61#[serde(rename_all = "camelCase")]
62pub struct ModelStorageObjectClonedSpec {
63 #[serde(flatten)]
64 pub reference: ModelStorageObjectRefSpec,
65
66 #[serde(default, flatten)]
67 pub owned: ModelStorageObjectOwnedSpec,
68}
69
70impl ModelStorageObjectClonedSpec {
71 #[inline]
72 fn endpoint(&self, namespace: &str) -> Option<Url> {
73 self.owned.endpoint(namespace)
74 }
75}
76
77#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
78#[serde(rename_all = "camelCase")]
79pub struct ModelStorageObjectOwnedSpec {
80 #[serde(default)]
81 pub minio_console_external_service: ModelStorageObjectOwnedExternalServiceSpec,
82
83 #[serde(default)]
84 pub minio_external_service: ModelStorageObjectOwnedExternalServiceSpec,
85
86 #[serde(default, flatten)]
87 pub replication: ModelStorageObjectOwnedReplicationSpec,
88
89 #[serde(default = "ModelStorageObjectOwnedSpec::default_runtime_class_name")]
90 pub runtime_class_name: String,
91
92 #[serde(default = "ModelStorageObjectOwnedSpec::default_storage_class_name")]
93 pub storage_class_name: String,
94}
95
96impl Default for ModelStorageObjectOwnedSpec {
97 fn default() -> Self {
98 Self {
99 minio_console_external_service: Default::default(),
100 minio_external_service: Default::default(),
101 replication: Default::default(),
102 runtime_class_name: Self::default_runtime_class_name(),
103 storage_class_name: Self::default_storage_class_name(),
104 }
105 }
106}
107
108impl ModelStorageObjectOwnedSpec {
109 fn default_runtime_class_name() -> String {
110 Default::default()
111 }
112
113 fn default_storage_class_name() -> String {
114 "ceph-block".into()
115 }
116
117 #[inline]
118 fn endpoint(&self, namespace: &str) -> Option<Url> {
119 get_object_storage_endpoint(namespace)
120 }
121}
122
123#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
124#[serde(rename_all = "camelCase")]
125pub struct ModelStorageObjectOwnedReplicationSpec {
126 #[serde(default = "ModelStorageObjectOwnedReplicationSpec::default_resources")]
127 pub resources: ResourceRequirements,
128
129 #[serde(default = "ModelStorageObjectOwnedReplicationSpec::default_total_nodes")]
130 pub total_nodes: u32,
131
132 #[serde(default = "ModelStorageObjectOwnedReplicationSpec::default_total_volumes_per_node")]
133 pub total_volumes_per_node: u32,
134}
135
136impl Default for ModelStorageObjectOwnedReplicationSpec {
137 fn default() -> Self {
138 Self {
139 resources: Self::default_resources(),
140 total_nodes: Self::default_total_nodes(),
141 total_volumes_per_node: Self::default_total_volumes_per_node(),
142 }
143 }
144}
145
146impl ModelStorageObjectOwnedReplicationSpec {
147 pub const fn default_resources_cpu() -> &'static str {
148 "8"
149 }
150
151 pub const fn default_resources_memory() -> &'static str {
152 "16Gi"
153 }
154
155 pub const fn default_resources_storage() -> &'static str {
156 "1TiB"
157 }
158
159 fn default_resources() -> ResourceRequirements {
160 ResourceRequirements {
161 limits: Some(btreemap! {
162 "cpu".into() => Quantity(Self::default_resources_cpu().into()),
163 "memory".into() => Quantity(Self::default_resources_memory().into()),
164 }),
165 requests: Some(btreemap! {
166 "storage".into() => Quantity(Self::default_resources_storage().into()),
167 }),
168 ..Default::default()
169 }
170 }
171
172 const fn default_total_nodes() -> u32 {
173 4
174 }
175
176 const fn default_total_volumes_per_node() -> u32 {
177 4
178 }
179}
180
181#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema)]
182#[serde(rename_all = "camelCase")]
183pub struct ModelStorageObjectOwnedExternalServiceSpec {
184 #[serde(default)]
185 pub address_pool: Option<String>,
186
187 #[serde(default)]
188 pub ip: Option<Ipv4Addr>,
189}
190
191impl ModelStorageObjectOwnedExternalServiceSpec {
192 pub const fn is_enabled(&self) -> bool {
193 self.address_pool.is_some() || self.ip.is_some()
194 }
195}
196
197#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
198#[serde(rename_all = "camelCase")]
199pub struct ModelStorageObjectRefSpec {
200 pub endpoint: Url,
201 #[serde(default)]
202 pub secret_ref: ModelUserAccessTokenSecretRefSpec,
203}
204
205impl ModelStorageObjectRefSpec {
206 #[inline]
207 fn endpoint(&self) -> Option<Url> {
208 Some(self.endpoint.clone())
209 }
210}
211
212#[inline]
213pub fn get_object_storage_endpoint(namespace: &str) -> Option<Url> {
214 format!("http://object-storage.{namespace}.svc")
215 .parse()
216 .ok()
217}
218
219#[inline]
220pub fn get_object_storage_owned_endpoint(namespace: &str) -> Option<Url> {
221 format!("http://minio.{namespace}.svc").parse().ok()
222}