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// ®ion_request.name,
255// ®ion_request.description,
256// ®ion_request.url,
257// ®ion_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// ®ion_request.name,
314// ®ion_request.description,
315// ®ion_request.url,
316// ®ion_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// }