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// ®ion_request.name,
253// ®ion_request.description,
254// ®ion_request.url,
255// ®ion_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// ®ion_request.name,
312// ®ion_request.description,
313// ®ion_request.url,
314// ®ion_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// }