omni_orchestrator/schemas/v1/api/
regions.rs

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