1use std::sync::Arc;
2use crate::DatabaseManager;
3use crate::schemas::v1::db::queries::storage;
4use rocket::http::Status;
5use rocket::serde::json::{json, Json, Value};
6use rocket::{get, State};
7use crate::schemas::v1::db::queries::{self as db};
8
9#[derive(FromForm, Default, Debug)]
11pub struct StorageClassQuery {
12 pub storage_type: Option<String>,
13 pub volume_binding_mode: Option<String>,
14 pub allow_volume_expansion: Option<bool>,
15}
16
17#[derive(FromForm, Default, Debug)]
19pub struct StorageVolumeQuery {
20 pub app_id: Option<i64>,
21 pub storage_class_id: Option<i64>,
22 pub status: Option<String>,
23 pub node_id: Option<i64>,
24 pub persistence_level: Option<String>,
25 pub write_concern: Option<String>,
26 pub page: Option<i64>,
27 pub per_page: Option<i64>,
28}
29
30#[get("/platform/<platform_id>/storage/classes?<query..>")]
32pub async fn list_storage_classes(
33 platform_id: i64,
34 query: StorageClassQuery,
35 db_manager: &State<Arc<DatabaseManager>>,
36) -> Result<Json<Value>, (Status, Json<Value>)> {
37 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
39 Ok(platform) => platform,
40 Err(_) => {
41 return Err((
42 Status::NotFound,
43 Json(json!({
44 "error": "Platform not found",
45 "message": format!("Platform with ID {} does not exist", platform_id)
46 }))
47 ));
48 }
49 };
50
51 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
53 Ok(pool) => pool,
54 Err(_) => {
55 return Err((
56 Status::InternalServerError,
57 Json(json!({
58 "error": "Database error",
59 "message": "Failed to connect to platform database"
60 }))
61 ));
62 }
63 };
64
65 let filter = storage::StorageClassFilter {
66 storage_type: query.storage_type,
67 volume_binding_mode: query.volume_binding_mode,
68 allow_volume_expansion: query.allow_volume_expansion,
69 };
70
71 match storage::list_storage_classes(&pool, filter).await {
72 Ok(storage_classes) => Ok(Json(json!({
73 "storage_classes": storage_classes
74 }))),
75 Err(_) => Err((
76 Status::InternalServerError,
77 Json(json!({
78 "error": "Database error",
79 "message": "Failed to list storage classes"
80 }))
81 )),
82 }
83}
84
85#[get("/platform/<platform_id>/storage/classes/<id>")]
87pub async fn get_storage_class(
88 platform_id: i64,
89 id: i64,
90 db_manager: &State<Arc<DatabaseManager>>,
91) -> Result<Json<Value>, (Status, Json<Value>)> {
92 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
94 Ok(platform) => platform,
95 Err(_) => {
96 return Err((
97 Status::NotFound,
98 Json(json!({
99 "error": "Platform not found",
100 "message": format!("Platform with ID {} does not exist", platform_id)
101 }))
102 ));
103 }
104 };
105
106 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
108 Ok(pool) => pool,
109 Err(_) => {
110 return Err((
111 Status::InternalServerError,
112 Json(json!({
113 "error": "Database error",
114 "message": "Failed to connect to platform database"
115 }))
116 ));
117 }
118 };
119
120 match storage::get_storage_class_by_id(&pool, id).await {
121 Ok(Some(storage_class)) => Ok(Json(json!({
122 "storage_class": storage_class
123 }))),
124 Ok(None) => Err((
125 Status::NotFound,
126 Json(json!({
127 "error": "Not found",
128 "message": format!("Storage class with ID {} does not exist", id)
129 }))
130 )),
131 Err(_) => Err((
132 Status::InternalServerError,
133 Json(json!({
134 "error": "Database error",
135 "message": "Failed to get storage class"
136 }))
137 )),
138 }
139}
140
141#[get("/platform/<platform_id>/storage/volumes?<query..>")]
143pub async fn list_storage_volumes(
144 platform_id: i64,
145 query: StorageVolumeQuery,
146 db_manager: &State<Arc<DatabaseManager>>,
147) -> Result<Json<Value>, (Status, Json<Value>)> {
148 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
150 Ok(platform) => platform,
151 Err(_) => {
152 return Err((
153 Status::NotFound,
154 Json(json!({
155 "error": "Platform not found",
156 "message": format!("Platform with ID {} does not exist", platform_id)
157 }))
158 ));
159 }
160 };
161
162 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
164 Ok(pool) => pool,
165 Err(_) => {
166 return Err((
167 Status::InternalServerError,
168 Json(json!({
169 "error": "Database error",
170 "message": "Failed to connect to platform database"
171 }))
172 ));
173 }
174 };
175
176 let page = query.page.unwrap_or(0);
177 let per_page = query.per_page.unwrap_or(10);
178
179 let filter = storage::StorageVolumeFilter {
180 app_id: query.app_id,
181 storage_class_id: query.storage_class_id,
182 status: query.status,
183 node_id: query.node_id,
184 persistence_level: query.persistence_level,
185 write_concern: query.write_concern,
186 };
187
188 let storage_volumes = match storage::list_storage_volumes(&pool, filter.clone(), page, per_page).await {
189 Ok(volumes) => volumes,
190 Err(_) => {
191 return Err((
192 Status::InternalServerError,
193 Json(json!({
194 "error": "Database error",
195 "message": "Failed to list storage volumes"
196 }))
197 ));
198 }
199 };
200
201 let total_count = match storage::count_storage_volumes_with_filter(&pool, &filter).await {
202 Ok(count) => count,
203 Err(_) => {
204 return Err((
205 Status::InternalServerError,
206 Json(json!({
207 "error": "Database error",
208 "message": "Failed to count storage volumes"
209 }))
210 ));
211 }
212 };
213
214 let total_pages = (total_count as f64 / per_page as f64).ceil() as i64;
215
216 Ok(Json(json!({
217 "storage_volumes": storage_volumes,
218 "pagination": {
219 "page": page,
220 "per_page": per_page,
221 "total_count": total_count,
222 "total_pages": total_pages
223 }
224 })))
225}
226
227#[get("/platform/<platform_id>/storage/classes/<id>/volumes?<page>&<per_page>")]
229pub async fn get_volumes_by_storage_class(
230 platform_id: i64,
231 id: i64,
232 page: Option<i64>,
233 per_page: Option<i64>,
234 db_manager: &State<Arc<DatabaseManager>>,
235) -> Result<Json<Value>, (Status, Json<Value>)> {
236 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
238 Ok(platform) => platform,
239 Err(_) => {
240 return Err((
241 Status::NotFound,
242 Json(json!({
243 "error": "Platform not found",
244 "message": format!("Platform with ID {} does not exist", platform_id)
245 }))
246 ));
247 }
248 };
249
250 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
252 Ok(pool) => pool,
253 Err(_) => {
254 return Err((
255 Status::InternalServerError,
256 Json(json!({
257 "error": "Database error",
258 "message": "Failed to connect to platform database"
259 }))
260 ));
261 }
262 };
263
264 match storage::get_storage_class_by_id(&pool, id).await {
266 Ok(Some(_)) => {},
267 Ok(None) => {
268 return Err((
269 Status::NotFound,
270 Json(json!({
271 "error": "Not found",
272 "message": format!("Storage class with ID {} does not exist", id)
273 }))
274 ));
275 },
276 Err(_) => {
277 return Err((
278 Status::InternalServerError,
279 Json(json!({
280 "error": "Database error",
281 "message": "Failed to verify storage class existence"
282 }))
283 ));
284 }
285 };
286
287 let page = page.unwrap_or(0);
288 let per_page = per_page.unwrap_or(10);
289
290 let volumes = match storage::get_volumes_by_storage_class(&pool, id, page, per_page).await {
291 Ok(volumes) => volumes,
292 Err(_) => {
293 return Err((
294 Status::InternalServerError,
295 Json(json!({
296 "error": "Database error",
297 "message": "Failed to fetch volumes by storage class"
298 }))
299 ));
300 }
301 };
302
303 let filter = storage::StorageVolumeFilter {
304 storage_class_id: Some(id),
305 ..Default::default()
306 };
307
308 let total_count = match storage::count_storage_volumes_with_filter(&pool, &filter).await {
309 Ok(count) => count,
310 Err(_) => {
311 return Err((
312 Status::InternalServerError,
313 Json(json!({
314 "error": "Database error",
315 "message": "Failed to count volumes"
316 }))
317 ));
318 }
319 };
320
321 let total_pages = (total_count as f64 / per_page as f64).ceil() as i64;
322
323 Ok(Json(json!({
324 "volumes": volumes,
325 "pagination": {
326 "page": page,
327 "per_page": per_page,
328 "total_count": total_count,
329 "total_pages": total_pages
330 }
331 })))
332}
333
334#[get("/platform/<platform_id>/storage/qos-policies")]
336pub async fn list_qos_policies(
337 platform_id: i64,
338 db_manager: &State<Arc<DatabaseManager>>,
339) -> Result<Json<Value>, (Status, Json<Value>)> {
340 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
342 Ok(platform) => platform,
343 Err(_) => {
344 return Err((
345 Status::NotFound,
346 Json(json!({
347 "error": "Platform not found",
348 "message": format!("Platform with ID {} does not exist", platform_id)
349 }))
350 ));
351 }
352 };
353
354 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
356 Ok(pool) => pool,
357 Err(_) => {
358 return Err((
359 Status::InternalServerError,
360 Json(json!({
361 "error": "Database error",
362 "message": "Failed to connect to platform database"
363 }))
364 ));
365 }
366 };
367
368 match storage::list_storage_qos_policies(&pool).await {
369 Ok(policies) => Ok(Json(json!({
370 "qos_policies": policies
371 }))),
372 Err(_) => Err((
373 Status::InternalServerError,
374 Json(json!({
375 "error": "Database error",
376 "message": "Failed to fetch QoS policies"
377 }))
378 )),
379 }
380}
381
382#[get("/platform/<platform_id>/storage/write-concerns/<write_concern>/volumes?<page>&<per_page>")]
384pub async fn list_volumes_by_write_concern(
385 platform_id: i64,
386 write_concern: String,
387 page: Option<i64>,
388 per_page: Option<i64>,
389 db_manager: &State<Arc<DatabaseManager>>,
390) -> Result<Json<Value>, (Status, Json<Value>)> {
391 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
393 Ok(platform) => platform,
394 Err(_) => {
395 return Err((
396 Status::NotFound,
397 Json(json!({
398 "error": "Platform not found",
399 "message": format!("Platform with ID {} does not exist", platform_id)
400 }))
401 ));
402 }
403 };
404
405 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
407 Ok(pool) => pool,
408 Err(_) => {
409 return Err((
410 Status::InternalServerError,
411 Json(json!({
412 "error": "Database error",
413 "message": "Failed to connect to platform database"
414 }))
415 ));
416 }
417 };
418
419 let page = page.unwrap_or(0);
420 let per_page = per_page.unwrap_or(10);
421
422 let volumes = match storage::get_volumes_by_write_concern(&pool, write_concern.clone(), page, per_page).await {
423 Ok(volumes) => volumes,
424 Err(_) => {
425 return Err((
426 Status::InternalServerError,
427 Json(json!({
428 "error": "Database error",
429 "message": "Failed to fetch volumes by write concern"
430 }))
431 ));
432 }
433 };
434
435 let filter = storage::StorageVolumeFilter {
436 write_concern: Some(write_concern),
437 ..Default::default()
438 };
439
440 let total_count = match storage::count_storage_volumes_with_filter(&pool, &filter).await {
441 Ok(count) => count,
442 Err(_) => {
443 return Err((
444 Status::InternalServerError,
445 Json(json!({
446 "error": "Database error",
447 "message": "Failed to count volumes"
448 }))
449 ));
450 }
451 };
452
453 let total_pages = (total_count as f64 / per_page as f64).ceil() as i64;
454
455 Ok(Json(json!({
456 "volumes": volumes,
457 "pagination": {
458 "page": page,
459 "per_page": per_page,
460 "total_count": total_count,
461 "total_pages": total_pages
462 }
463 })))
464}
465
466#[get("/platform/<platform_id>/storage/persistence-levels/<persistence_level>/volumes?<page>&<per_page>")]
468pub async fn list_volumes_by_persistence_level(
469 platform_id: i64,
470 persistence_level: String,
471 page: Option<i64>,
472 per_page: Option<i64>,
473 db_manager: &State<Arc<DatabaseManager>>,
474) -> Result<Json<Value>, (Status, Json<Value>)> {
475 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
477 Ok(platform) => platform,
478 Err(_) => {
479 return Err((
480 Status::NotFound,
481 Json(json!({
482 "error": "Platform not found",
483 "message": format!("Platform with ID {} does not exist", platform_id)
484 }))
485 ));
486 }
487 };
488
489 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
491 Ok(pool) => pool,
492 Err(_) => {
493 return Err((
494 Status::InternalServerError,
495 Json(json!({
496 "error": "Database error",
497 "message": "Failed to connect to platform database"
498 }))
499 ));
500 }
501 };
502
503 let page = page.unwrap_or(0);
504 let per_page = per_page.unwrap_or(10);
505
506 let volumes = match storage::get_volumes_by_persistence_level(&pool, persistence_level.clone(), page, per_page).await {
507 Ok(volumes) => volumes,
508 Err(_) => {
509 return Err((
510 Status::InternalServerError,
511 Json(json!({
512 "error": "Database error",
513 "message": "Failed to fetch volumes by persistence level"
514 }))
515 ));
516 }
517 };
518
519 let filter = storage::StorageVolumeFilter {
520 persistence_level: Some(persistence_level),
521 ..Default::default()
522 };
523
524 let total_count = match storage::count_storage_volumes_with_filter(&pool, &filter).await {
525 Ok(count) => count,
526 Err(_) => {
527 return Err((
528 Status::InternalServerError,
529 Json(json!({
530 "error": "Database error",
531 "message": "Failed to count volumes"
532 }))
533 ));
534 }
535 };
536
537 let total_pages = (total_count as f64 / per_page as f64).ceil() as i64;
538
539 Ok(Json(json!({
540 "volumes": volumes,
541 "pagination": {
542 "page": page,
543 "per_page": per_page,
544 "total_count": total_count,
545 "total_pages": total_pages
546 }
547 })))
548}
549
550#[get("/platform/<platform_id>/storage/regions/<region_id>/volumes?<page>&<per_page>")]
552pub async fn get_volumes_for_region_route(
553 platform_id: i64,
554 region_id: i64,
555 page: Option<i64>,
556 per_page: Option<i64>,
557 db_manager: &State<Arc<DatabaseManager>>,
558) -> Result<Json<Value>, (Status, Json<Value>)> {
559 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
561 Ok(platform) => platform,
562 Err(_) => {
563 return Err((
564 Status::NotFound,
565 Json(json!({
566 "error": "Platform not found",
567 "message": format!("Platform with ID {} does not exist", platform_id)
568 }))
569 ));
570 }
571 };
572
573 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
575 Ok(pool) => pool,
576 Err(_) => {
577 return Err((
578 Status::InternalServerError,
579 Json(json!({
580 "error": "Database error",
581 "message": "Failed to connect to platform database"
582 }))
583 ));
584 }
585 };
586
587 let page = page.unwrap_or(0);
588 let per_page = per_page.unwrap_or(10);
589
590 let region_volumes = match storage::get_volumes_for_region(&pool, region_id, page, per_page).await {
591 Ok(volumes) => volumes,
592 Err(_) => {
593 return Err((
594 Status::InternalServerError,
595 Json(json!({
596 "error": "Database error",
597 "message": "Failed to fetch volumes for region"
598 }))
599 ));
600 }
601 };
602
603 let total_count = match storage::count_volumes_for_region(&pool, region_id).await {
604 Ok(count) => count,
605 Err(_) => {
606 return Err((
607 Status::InternalServerError,
608 Json(json!({
609 "error": "Database error",
610 "message": "Failed to count volumes for region"
611 }))
612 ));
613 }
614 };
615
616 let total_pages = (total_count as f64 / per_page as f64).ceil() as i64;
617
618 Ok(Json(json!({
619 "region": region_volumes.region,
620 "volumes": region_volumes.volumes,
621 "pagination": {
622 "page": page,
623 "per_page": per_page,
624 "total_count": total_count,
625 "total_pages": total_pages
626 }
627 })))
628}
629
630#[get("/platform/<platform_id>/storage/providers/<provider_id>/volumes?<page>&<per_page>")]
632pub async fn get_storage_volumes_for_provider(
633 platform_id: i64,
634 provider_id: i64,
635 page: Option<i64>,
636 per_page: Option<i64>,
637 db_manager: &State<Arc<DatabaseManager>>,
638) -> Result<Json<Value>, (Status, Json<Value>)> {
639 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
641 Ok(platform) => platform,
642 Err(_) => {
643 return Err((
644 Status::NotFound,
645 Json(json!({
646 "error": "Platform not found",
647 "message": format!("Platform with ID {} does not exist", platform_id)
648 }))
649 ));
650 }
651 };
652
653 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
655 Ok(pool) => pool,
656 Err(_) => {
657 return Err((
658 Status::InternalServerError,
659 Json(json!({
660 "error": "Database error",
661 "message": "Failed to connect to platform database"
662 }))
663 ));
664 }
665 };
666
667 let page = page.unwrap_or(0);
668 let per_page = per_page.unwrap_or(10);
669
670 let volumes = match storage::get_volumes_for_provider(&pool, provider_id, page, per_page).await {
671 Ok(volumes) => volumes,
672 Err(_) => {
673 return Err((
674 Status::InternalServerError,
675 Json(json!({
676 "error": "Database error",
677 "message": "Failed to fetch volumes for provider"
678 }))
679 ));
680 }
681 };
682
683 let total_count = match storage::count_volumes_for_provider(&pool, provider_id).await {
684 Ok(count) => count,
685 Err(_) => {
686 return Err((
687 Status::InternalServerError,
688 Json(json!({
689 "error": "Database error",
690 "message": "Failed to count volumes for provider"
691 }))
692 ));
693 }
694 };
695
696 let total_pages = (total_count as f64 / per_page as f64).ceil() as i64;
697
698 Ok(Json(json!({
699 "provider_id": provider_id,
700 "volumes": volumes,
701 "pagination": {
702 "page": page,
703 "per_page": per_page,
704 "total_count": total_count,
705 "total_pages": total_pages
706 }
707 })))
708}