omni_orchestrator/schemas/v1/api/
regions.rs

1use crate::DatabaseManager;
2use crate::models::region::Region;
3use crate::models::provider::ProviderRegion;
4use crate::schemas::v1::db::queries::{self as db};
5use rocket::http::Status;
6use rocket::serde::json::{json, Json, Value};
7use rocket::{delete, get, http::ContentType, post, put, Data, State};
8use serde::{Deserialize, Serialize};
9use sqlx::MySql;
10use std::collections::HashMap;
11use std::sync::Arc;
12use tokio::sync::RwLock;
13
14#[derive(Debug, Serialize, Deserialize)]
15pub struct CreateRegionRequest {
16    /// The name of the region, e.g. 'us-east-1'
17    name: String,
18    /// A human-friendly name for the region, e.g. 'US East'
19    display_name: String,
20    /// What provider is responsible for this region? eg. 'kubernetes', 'docker', 'aws', 'gcp', 'azure', 'detee'
21    provider: String,
22    /// What does your cloud provicer call this region? e.g. 'us-east-1'
23    provider_region: Option<String>,
24    /// Country / State / province / City in which the data center is located
25    location: Option<String>,
26    /// Coordinates for the region, can be used for geolocation or mapping
27    coordinates: Option<String>, // Will need conversion to POINT in DB layer
28    /// The status of the region, can be used to indicate if the region is usable or not
29    status: Option<String>, // ENUM('active', 'maintenance', 'offline', 'deprecated')
30    /// Can be used to indicate if the region is visible and usable to all orgs
31    is_public: Option<bool>,
32    /// If you have multiple types of regions, for certain kinds of compute optimization
33    class: Option<String>,
34}
35
36#[derive(Debug, Serialize, Deserialize)]
37pub struct UpdateRegionRequest {
38    name: String,
39    description: String,
40    url: String,
41    org_id: i64,
42}
43
44// List all regions paginated
45#[get("/platform/<platform_id>/regions?<page>&<per_page>")]
46pub async fn list_regions(
47    platform_id: i64,
48    page: Option<i64>,
49    per_page: Option<i64>,
50    db_manager: &State<Arc<DatabaseManager>>,
51) -> Result<Json<Vec<Region>>, (Status, Json<Value>)> {
52    // Get platform information
53    let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
54        Ok(platform) => platform,
55        Err(_) => {
56            return Err((
57                Status::NotFound,
58                Json(json!({
59                    "error": "Platform not found",
60                    "message": format!("Platform with ID {} does not exist", platform_id)
61                }))
62            ));
63        }
64    };
65
66    // Get platform-specific database pool
67    let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
68        Ok(pool) => pool,
69        Err(_) => {
70            return Err((
71                Status::InternalServerError,
72                Json(json!({
73                    "error": "Database error",
74                    "message": "Failed to connect to platform database"
75                }))
76            ));
77        }
78    };
79
80    let regions = match db::region::list_regions(&pool, page, per_page).await {
81        Ok(regions) => regions,
82        Err(_) => {
83            return Err((
84                Status::InternalServerError,
85                Json(json!({
86                    "error": "Database error",
87                    "message": "Failed to list regions"
88                }))
89            ));
90        }
91    };
92    
93    println!("Found {} regions", regions.len());
94    let regions_vec: Vec<Region> = regions.into_iter().collect();
95    println!("Returning {} regions", regions_vec.len());
96    
97    Ok(Json(regions_vec))
98}
99
100#[get("/platform/<platform_id>/provider_regions")]
101pub async fn list_provider_regions(
102    platform_id: i64,
103    db_manager: &State<Arc<DatabaseManager>>,
104) -> Result<Json<Vec<ProviderRegion>>, (Status, Json<Value>)> {
105    // Get platform information
106    let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
107        Ok(platform) => platform,
108        Err(_) => {
109            return Err((
110                Status::NotFound,
111                Json(json!({
112                    "error": "Platform not found",
113                    "message": format!("Platform with ID {} does not exist", platform_id)
114                }))
115            ));
116        }
117    };
118
119    // Get platform-specific database pool
120    let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
121        Ok(pool) => pool,
122        Err(_) => {
123            return Err((
124                Status::InternalServerError,
125                Json(json!({
126                    "error": "Database error",
127                    "message": "Failed to connect to platform database"
128                }))
129            ));
130        }
131    };
132
133    let regions = match db::region::list_provider_regions(&pool).await {
134        Ok(regions) => regions,
135        Err(_) => {
136            return Err((
137                Status::InternalServerError,
138                Json(json!({
139                    "error": "Database error",
140                    "message": "Failed to list provider regions"
141                }))
142            ));
143        }
144    };
145    
146    println!("Found {} provider regions", regions.len());
147    let regions_vec: Vec<ProviderRegion> = regions.into_iter().collect();
148    println!("Returning {} provider regions", regions_vec.len());
149    
150    Ok(Json(regions_vec))
151}
152
153// Here are the commented routes updated to be platform-specific:
154
155// // Get a single region by ID
156// #[get("/platform/<platform_id>/regions/<id>")]
157// pub async fn get_region(
158//     platform_id: i64,
159//     id: String, 
160//     db_manager: &State<Arc<DatabaseManager>>
161// ) -> Result<Json<Region>, (Status, Json<Value>)> {
162//     // Get platform information
163//     let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
164//         Ok(platform) => platform,
165//         Err(_) => {
166//             return Err((
167//                 Status::NotFound,
168//                 Json(json!({
169//                     "error": "Platform not found",
170//                     "message": format!("Platform with ID {} does not exist", platform_id)
171//                 }))
172//             ));
173//         }
174//     };
175//
176//     // Get platform-specific database pool
177//     let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
178//         Ok(pool) => pool,
179//         Err(_) => {
180//             return Err((
181//                 Status::InternalServerError,
182//                 Json(json!({
183//                     "error": "Database error",
184//                     "message": "Failed to connect to platform database"
185//                 }))
186//             ));
187//         }
188//     };
189//
190//     let region = match db::region::get_region_by_id(&pool, &id).await {
191//         Ok(Some(region)) => region,
192//         Ok(None) => {
193//             return Err((
194//                 Status::NotFound,
195//                 Json(json!({
196//                     "error": "Region not found",
197//                     "message": format!("Region with ID {} does not exist", id)
198//                 }))
199//             ));
200//         },
201//         Err(_) => {
202//             return Err((
203//                 Status::InternalServerError,
204//                 Json(json!({
205//                     "error": "Database error",
206//                     "message": "Failed to retrieve region"
207//                 }))
208//             ));
209//         }
210//     };
211//     
212//     Ok(Json(region))
213// }
214//
215// // Create a new region
216// #[post("/platform/<platform_id>/regions", format = "json", data = "<region_request>")]
217// pub async fn create_region(
218//     platform_id: i64,
219//     region_request: Json<CreateRegionRequest>,
220//     db_manager: &State<Arc<DatabaseManager>>
221// ) -> Result<Json<Region>, (Status, Json<Value>)> {
222//     // Get platform information
223//     let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
224//         Ok(platform) => platform,
225//         Err(_) => {
226//             return Err((
227//                 Status::NotFound,
228//                 Json(json!({
229//                     "error": "Platform not found",
230//                     "message": format!("Platform with ID {} does not exist", platform_id)
231//                 }))
232//             ));
233//         }
234//     };
235//
236//     // Get platform-specific database pool
237//     let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
238//         Ok(pool) => pool,
239//         Err(_) => {
240//             return Err((
241//                 Status::InternalServerError,
242//                 Json(json!({
243//                     "error": "Database error",
244//                     "message": "Failed to connect to platform database"
245//                 }))
246//             ));
247//         }
248//     };
249//
250//     let region = match db::region::create_region(
251//         &pool,
252//         &region_request.name,
253//         &region_request.description,
254//         &region_request.url,
255//         &region_request.org_id
256//     ).await {
257//         Ok(region) => region,
258//         Err(_) => {
259//             return Err((
260//                 Status::InternalServerError,
261//                 Json(json!({
262//                     "error": "Database error",
263//                     "message": "Failed to create region"
264//                 }))
265//             ));
266//         }
267//     };
268//     
269//     Ok(Json(region))
270// }
271//
272// // Update an existing region
273// #[put("/platform/<platform_id>/regions/<id>", format = "json", data = "<region_request>")]
274// pub async fn update_region(
275//     platform_id: i64,
276//     id: String,
277//     region_request: Json<UpdateRegionRequest>,
278//     db_manager: &State<Arc<DatabaseManager>>
279// ) -> Result<Json<Region>, (Status, Json<Value>)> {
280//     // Get platform information
281//     let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
282//         Ok(platform) => platform,
283//         Err(_) => {
284//             return Err((
285//                 Status::NotFound,
286//                 Json(json!({
287//                     "error": "Platform not found",
288//                     "message": format!("Platform with ID {} does not exist", platform_id)
289//                 }))
290//             ));
291//         }
292//     };
293//
294//     // Get platform-specific database pool
295//     let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
296//         Ok(pool) => pool,
297//         Err(_) => {
298//             return Err((
299//                 Status::InternalServerError,
300//                 Json(json!({
301//                     "error": "Database error",
302//                     "message": "Failed to connect to platform database"
303//                 }))
304//             ));
305//         }
306//     };
307//
308//     let region = match db::region::update_region(
309//         &pool,
310//         &id,
311//         &region_request.name,
312//         &region_request.description,
313//         &region_request.url,
314//         &region_request.org_id
315//     ).await {
316//         Ok(region) => region,
317//         Err(_) => {
318//             return Err((
319//                 Status::InternalServerError,
320//                 Json(json!({
321//                     "error": "Database error",
322//                     "message": "Failed to update region"
323//                 }))
324//             ));
325//         }
326//     };
327//     
328//     Ok(Json(region))
329// }
330//
331// // Delete a region
332// #[delete("/platform/<platform_id>/regions/<id>")]
333// pub async fn delete_region(
334//     platform_id: i64,
335//     id: String, 
336//     db_manager: &State<Arc<DatabaseManager>>
337// ) -> Result<Status, (Status, Json<Value>)> {
338//     // Get platform information
339//     let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
340//         Ok(platform) => platform,
341//         Err(_) => {
342//             return Err((
343//                 Status::NotFound,
344//                 Json(json!({
345//                     "error": "Platform not found",
346//                     "message": format!("Platform with ID {} does not exist", platform_id)
347//                 }))
348//             ));
349//         }
350//     };
351//
352//     // Get platform-specific database pool
353//     let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
354//         Ok(pool) => pool,
355//         Err(_) => {
356//             return Err((
357//                 Status::InternalServerError,
358//                 Json(json!({
359//                     "error": "Database error",
360//                     "message": "Failed to connect to platform database"
361//                 }))
362//             ));
363//         }
364//     };
365//
366//     match db::region::delete_region(&pool, &id).await {
367//         Ok(_) => Ok(Status::NoContent),
368//         Err(_) => {
369//             return Err((
370//                 Status::InternalServerError,
371//                 Json(json!({
372//                     "error": "Database error",
373//                     "message": "Failed to delete region"
374//                 }))
375//             ));
376//         }
377//     }
378// }