cdl_openapi/
model_storage_binding.rs

1use chrono::{DateTime, Utc};
2use k8s_openapi::api::core::v1::ResourceRequirements;
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5use strum::{Display, EnumString};
6
7use crate::{model::ModelSpec, model_storage::ModelStorageSpec};
8
9#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
10#[cfg_attr(feature = "k8s", derive(::kube::CustomResource))]
11#[cfg_attr(
12    feature = "k8s",
13    kube(
14        group = "cdl.ulagbulag.io",
15        version = "v1alpha1",
16        kind = "ModelStorageBinding",
17        root = "ModelStorageBindingCrd",
18        status = "ModelStorageBindingStatus",
19        shortname = "msb",
20        namespaced,
21        printcolumn = r#"{
22            "name": "state",
23            "type": "string",
24            "description": "state of the binding",
25            "jsonPath": ".status.state"
26        }"#,
27        printcolumn = r#"{
28            "name": "created-at",
29            "type": "date",
30            "description": "created time",
31            "jsonPath": ".metadata.creationTimestamp"
32        }"#,
33        printcolumn = r#"{
34            "name": "updated-at",
35            "type": "date",
36            "description": "updated time",
37            "jsonPath": ".status.lastUpdated"
38        }"#,
39        printcolumn = r#"{
40            "name": "version",
41            "type": "integer",
42            "description": "binding version",
43            "jsonPath": ".metadata.generation"
44        }"#,
45    )
46)]
47#[serde(rename_all = "camelCase")]
48pub struct ModelStorageBindingSpec {
49    #[serde(default)]
50    pub deletion_policy: ModelStorageBindingDeletionPolicy,
51    pub model: String,
52    #[serde(default)]
53    pub resources: Option<ResourceRequirements>,
54    pub storage: ModelStorageBindingStorageKind<String>,
55}
56
57#[cfg(feature = "k8s")]
58impl ModelStorageBindingCrd {
59    pub const FINALIZER_NAME: &'static str = "cdl.ulagbulag.io/finalizer-model-storage-bindings";
60}
61
62#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
63#[serde(rename_all = "camelCase")]
64pub enum ModelStorageBindingStorageKind<Storage> {
65    Cloned(ModelStorageBindingStorageKindClonedSpec<Storage>),
66    Owned(ModelStorageBindingStorageKindOwnedSpec<Storage>),
67}
68
69impl<Storage> ModelStorageBindingStorageKind<Storage> {
70    pub fn source(&self) -> Option<(&Storage, ModelStorageBindingSyncPolicy)> {
71        match self {
72            Self::Cloned(spec) => Some((&spec.source, spec.sync_policy)),
73            Self::Owned(_) => None,
74        }
75    }
76
77    pub fn source_binding_name(&self) -> Option<&str> {
78        match self {
79            Self::Cloned(spec) => spec.source_binding_name.as_deref(),
80            Self::Owned(_) => None,
81        }
82    }
83
84    pub fn sync_policy(&self) -> Option<ModelStorageBindingSyncPolicy> {
85        match self {
86            Self::Cloned(spec) => Some(spec.sync_policy),
87            Self::Owned(_) => None,
88        }
89    }
90
91    pub fn target(&self) -> &Storage {
92        match self {
93            Self::Cloned(spec) => &spec.target,
94            Self::Owned(spec) => &spec.target,
95        }
96    }
97
98    pub fn into_target(self) -> Storage {
99        match self {
100            Self::Cloned(spec) => spec.target,
101            Self::Owned(spec) => spec.target,
102        }
103    }
104}
105
106#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
107#[serde(rename_all = "camelCase")]
108pub struct ModelStorageBindingStorageKindClonedSpec<Storage> {
109    pub source: Storage,
110    #[serde(default)]
111    pub source_binding_name: Option<String>,
112    pub target: Storage,
113    #[serde(default)]
114    pub sync_policy: ModelStorageBindingSyncPolicy,
115}
116
117#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
118#[serde(rename_all = "camelCase")]
119pub struct ModelStorageBindingStorageSpec<'name, Storage> {
120    pub source: Option<ModelStorageBindingStorageSourceSpec<'name, Storage>>,
121    pub source_binding_name: Option<&'name str>,
122    pub target: Storage,
123    pub target_name: &'name str,
124}
125
126#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
127#[serde(rename_all = "camelCase")]
128pub struct ModelStorageBindingStorageSourceSpec<'name, Storage> {
129    pub name: &'name str,
130    pub storage: Storage,
131    pub sync_policy: ModelStorageBindingSyncPolicy,
132}
133
134impl<'name, Storage> ModelStorageBindingStorageSourceSpec<'name, Storage> {
135    pub fn as_deref(&self) -> ModelStorageBindingStorageSourceSpec<'name, &'_ Storage> {
136        ModelStorageBindingStorageSourceSpec {
137            name: self.name,
138            storage: &self.storage,
139            sync_policy: self.sync_policy,
140        }
141    }
142}
143
144#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
145#[serde(rename_all = "camelCase")]
146pub struct ModelStorageBindingStorageKindOwnedSpec<Storage> {
147    pub target: Storage,
148}
149
150#[derive(
151    Copy,
152    Clone,
153    Debug,
154    Default,
155    PartialEq,
156    Eq,
157    PartialOrd,
158    Ord,
159    Hash,
160    Serialize,
161    Deserialize,
162    JsonSchema,
163)]
164#[serde(rename_all = "camelCase")]
165pub struct ModelStorageBindingSyncPolicy {
166    #[serde(default)]
167    pub pull: ModelStorageBindingSyncPolicyPull,
168    #[serde(default)]
169    pub push: ModelStorageBindingSyncPolicyPush,
170}
171
172impl ModelStorageBindingSyncPolicy {
173    pub fn is_none(&self) -> bool {
174        self.pull == ModelStorageBindingSyncPolicyPull::Never
175            && self.push == ModelStorageBindingSyncPolicyPush::Never
176    }
177}
178
179#[derive(
180    Copy,
181    Clone,
182    Debug,
183    Display,
184    Default,
185    EnumString,
186    PartialEq,
187    Eq,
188    PartialOrd,
189    Ord,
190    Hash,
191    Serialize,
192    Deserialize,
193    JsonSchema,
194)]
195pub enum ModelStorageBindingSyncPolicyPull {
196    #[default]
197    Always,
198    OnCreate,
199    Never,
200}
201
202#[derive(
203    Copy,
204    Clone,
205    Debug,
206    Display,
207    Default,
208    EnumString,
209    PartialEq,
210    Eq,
211    PartialOrd,
212    Ord,
213    Hash,
214    Serialize,
215    Deserialize,
216    JsonSchema,
217)]
218pub enum ModelStorageBindingSyncPolicyPush {
219    #[default]
220    Always,
221    OnDelete,
222    Never,
223}
224
225#[derive(
226    Copy,
227    Clone,
228    Debug,
229    Display,
230    Default,
231    EnumString,
232    PartialEq,
233    Eq,
234    PartialOrd,
235    Ord,
236    Hash,
237    Serialize,
238    Deserialize,
239    JsonSchema,
240)]
241pub enum ModelStorageBindingDeletionPolicy {
242    Delete,
243    #[default]
244    Retain,
245}
246
247#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
248#[serde(rename_all = "camelCase")]
249pub struct ModelStorageBindingStatus {
250    #[serde(default)]
251    pub state: ModelStorageBindingState,
252    #[serde(default)]
253    pub deletion_policy: ModelStorageBindingDeletionPolicy,
254    #[serde(default)]
255    pub model: Option<ModelSpec>,
256    #[serde(default)]
257    pub model_name: Option<String>,
258    #[serde(default)]
259    pub resources: Option<ResourceRequirements>,
260    #[serde(default)]
261    pub storage_source: Option<ModelStorageSpec>,
262    #[serde(default)]
263    pub storage_source_binding_name: Option<String>,
264    #[serde(default)]
265    pub storage_source_name: Option<String>,
266    #[serde(default)]
267    pub storage_source_uid: Option<String>,
268    #[serde(default)]
269    pub storage_sync_policy: Option<ModelStorageBindingSyncPolicy>,
270    #[serde(default)]
271    pub storage_target: Option<ModelStorageSpec>,
272    #[serde(default)]
273    pub storage_target_name: Option<String>,
274    #[serde(default)]
275    pub storage_target_uid: Option<String>,
276    pub last_updated: DateTime<Utc>,
277}
278
279#[derive(
280    Copy,
281    Clone,
282    Debug,
283    Display,
284    Default,
285    EnumString,
286    PartialEq,
287    Eq,
288    PartialOrd,
289    Ord,
290    Hash,
291    Serialize,
292    Deserialize,
293    JsonSchema,
294)]
295pub enum ModelStorageBindingState {
296    #[default]
297    Pending,
298    Ready,
299    Deleting,
300}