-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #17 from DioCrafts/feature/frontend-helm-chart
fixing API Rest errors - Split App States
- Loading branch information
Showing
14 changed files
with
286 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
//src/backends/mods.rs | ||
pub mod handlers; | ||
pub mod routes; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
//src/backends/routers.rs | ||
use actix_web::web; | ||
use super::handlers; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,188 @@ | ||
//src/rest/handlers.rs | ||
//! REST API Handlers | ||
//! | ||
//! These functions handle incoming HTTP requests and return appropriate responses. | ||
use actix_web::{web, HttpResponse, Responder}; | ||
use serde_json::json; | ||
use crate::backends::handlers::AppState as BackendsState; | ||
use crate::security::handlers::{AppState as SecurityState, SecurityPolicy}; | ||
use crate::observability::handlers::ObservabilityState; | ||
|
||
use crate::backends::handlers::Backend; | ||
use kube::Client; | ||
use crate::gateway::crd::gateway::GatewayManager; | ||
|
||
/// Handler for `GET /api/metrics` | ||
/// | ||
/// Returns a list of metrics (mocked example data for now). | ||
pub async fn get_metrics() -> impl Responder { | ||
let metrics = json!([ | ||
{ "timestamp": "2024-11-17T12:00:00Z", "rps": 150, "latency": 200, "errors": 5 }, | ||
{ "timestamp": "2024-11-17T12:01:00Z", "rps": 160, "latency": 180, "errors": 3 } | ||
]); | ||
HttpResponse::Ok().json(metrics) | ||
} | ||
|
||
/// Handler for `GET /api/backends` | ||
/// | ||
/// Returns a list of backend services. | ||
pub async fn get_backends() -> impl Responder { | ||
let backends = json!([ | ||
{ "id": 1, "name": "Backend 1", "address": "192.168.1.10", "port": 80, "status": "Healthy" }, | ||
{ "id": 2, "name": "Backend 2", "address": "192.168.1.11", "port": 8080, "status": "Unhealthy" } | ||
]); | ||
HttpResponse::Ok().json(backends) | ||
/// Delegates to the backend module to list backends. | ||
pub async fn get_backends(data: web::Data<BackendsState>) -> impl Responder { | ||
crate::backends::handlers::list_backends(data).await | ||
} | ||
|
||
/// Handler for `POST /api/backends` | ||
/// | ||
/// Adds a new backend service. | ||
pub async fn add_backend(backend: web::Json<serde_json::Value>) -> impl Responder { | ||
println!("Adding new backend: {:?}", backend); | ||
HttpResponse::Created().json(json!({ "message": "Backend added", "backend": backend })) | ||
pub async fn add_backend( | ||
app_state: web::Data<BackendsState>, | ||
backend: web::Json<Backend>, | ||
) -> impl Responder { | ||
let mut backends = app_state.backends.lock().unwrap(); | ||
let mut new_backend = backend.into_inner(); | ||
new_backend.id = backends.last().map_or(1, |b| b.id + 1); | ||
new_backend.status = "Unknown".to_string(); | ||
backends.push(new_backend); | ||
|
||
HttpResponse::Created().json(json!({ "message": "Backend added successfully" })) | ||
} | ||
|
||
/// Handler for `DELETE /api/backends/{id}` | ||
/// | ||
/// Deletes a backend service by ID. | ||
pub async fn delete_backend(path: web::Path<u32>) -> impl Responder { | ||
let id = path.into_inner(); // Extraer el valor de Path | ||
println!("Deleting backend with ID: {}", id); | ||
HttpResponse::Ok().json(json!({ "message": "Backend deleted", "id": id })) | ||
pub async fn delete_backend( | ||
app_state: web::Data<BackendsState>, | ||
id: web::Path<u32>, | ||
) -> impl Responder { | ||
let mut backends = app_state.backends.lock().unwrap(); | ||
let id = id.into_inner(); | ||
let initial_len = backends.len(); | ||
backends.retain(|backend| backend.id != id); | ||
|
||
if backends.len() < initial_len { | ||
HttpResponse::Ok().json(json!({ "message": "Backend deleted successfully", "id": id })) | ||
} else { | ||
HttpResponse::NotFound().json(json!({ "error": "Backend not found", "id": id })) | ||
} | ||
} | ||
|
||
/// Handler for `GET /api/security/policies` | ||
/// | ||
/// Retrieves a list of security policies. | ||
pub async fn get_policies(data: web::Data<SecurityState>) -> impl Responder { | ||
let policies = data.policies.lock().unwrap(); | ||
HttpResponse::Ok().json(&*policies) | ||
} | ||
|
||
/// Handler for `POST /api/security/policies` | ||
/// | ||
/// Adds a new security policy. | ||
pub async fn add_policy( | ||
data: web::Data<SecurityState>, | ||
policy: web::Json<SecurityPolicy>, | ||
) -> impl Responder { | ||
let mut policies = data.policies.lock().unwrap(); | ||
let mut new_policy = policy.into_inner(); | ||
new_policy.id = policies.last().map_or(1, |p| p.id + 1); | ||
policies.push(new_policy); | ||
|
||
HttpResponse::Created().json(json!({ "message": "Policy added successfully" })) | ||
} | ||
|
||
/// Handler for `GET /api/alerts` | ||
|
||
/// Handler for `GET /api/gateways` | ||
/// | ||
/// Returns a list of alerts (mocked example data for now). | ||
pub async fn get_alerts() -> impl Responder { | ||
let alerts = json!([ | ||
{ "id": 1, "message": "High latency detected" }, | ||
{ "id": 2, "message": "Backend unreachable" } | ||
]); | ||
HttpResponse::Ok().json(alerts) | ||
/// Returns a list of gateways from the Kubernetes cluster. | ||
pub async fn get_gateways(client: web::Data<Client>) -> impl Responder { | ||
let manager = GatewayManager::new(client.get_ref().clone()); | ||
|
||
match manager.list_gateways("default").await { | ||
Ok(gateways) => HttpResponse::Ok().json(gateways), | ||
Err(e) => { | ||
eprintln!("Error listing Gateways: {:?}", e); | ||
HttpResponse::InternalServerError().body("Failed to list Gateways.") | ||
} | ||
} | ||
} | ||
|
||
/// Handler for `POST /api/gateways` | ||
pub async fn add_gateway( | ||
client: web::Data<Client>, | ||
gateway: web::Json<crate::gateway::models::Gateway>, | ||
) -> impl Responder { | ||
let manager = GatewayManager::new(client.get_ref().clone()); | ||
let gateway_spec = crate::gateway::crd::gateway::GatewaySpec { | ||
spec: crate::gateway::crd::gateway::GatewayInnerSpec { | ||
hostname: gateway.hostname.clone(), | ||
tls_enabled: gateway.tls_enabled, | ||
certificate: gateway.certificate.clone(), | ||
routes: gateway.routes.iter().cloned().map(Into::into).collect(), | ||
}, | ||
}; | ||
|
||
match manager.create_gateway("default", &gateway_spec).await { | ||
Ok(_) => HttpResponse::Created().json(json!({ "message": "Gateway created successfully." })), | ||
Err(e) => { | ||
eprintln!("Error creating Gateway: {:?}", e); | ||
HttpResponse::InternalServerError().body("Failed to create Gateway.") | ||
} | ||
} | ||
} | ||
|
||
/// Handler for `DELETE /api/gateways/{id}` | ||
pub async fn delete_gateway( | ||
client: web::Data<Client>, | ||
id: web::Path<String>, | ||
) -> impl Responder { | ||
let manager = GatewayManager::new(client.get_ref().clone()); | ||
|
||
match manager.delete_gateway("default", &id.into_inner()).await { | ||
Ok(_) => HttpResponse::Ok().json(json!({ "message": "Gateway deleted successfully." })), | ||
Err(e) => { | ||
eprintln!("Error deleting Gateway: {:?}", e); | ||
HttpResponse::InternalServerError().body("Failed to delete Gateway.") | ||
} | ||
} | ||
} | ||
|
||
/// Handler for `GET /api/metrics` | ||
/// | ||
/// Returns a list of metrics (from Observability module). | ||
pub async fn get_metrics(data: web::Data<ObservabilityState>) -> impl Responder { | ||
let metrics = data.metrics.lock().unwrap(); | ||
HttpResponse::Ok().json(&*metrics) | ||
} | ||
|
||
/// Handler for `GET /api/observability/alerts` | ||
/// | ||
/// Returns a list of alerts from Observability state. | ||
pub async fn get_observability_alerts(data: web::Data<ObservabilityState>) -> impl Responder { | ||
let alerts = data.alerts.lock().unwrap(); // Acceso al nuevo campo `alerts` | ||
HttpResponse::Ok().json(&*alerts) | ||
} | ||
|
||
|
||
/// Handler for `GET /api/observability/logs` | ||
/// | ||
/// Returns a list of logs from Observability state. | ||
pub async fn get_logs(data: web::Data<ObservabilityState>) -> impl Responder { | ||
let logs = data.logs.lock().unwrap(); | ||
HttpResponse::Ok().json(&*logs) | ||
} | ||
|
||
|
||
/// Handler for `DELETE /api/security/policies/{id}` | ||
/// | ||
/// Deletes a security policy by ID. | ||
pub async fn delete_policy( | ||
data: web::Data<SecurityState>, | ||
id: web::Path<u32>, | ||
) -> impl Responder { | ||
let mut policies = data.policies.lock().unwrap(); | ||
let id = *id; | ||
let initial_len = policies.len(); | ||
policies.retain(|policy| policy.id != id); | ||
|
||
if policies.len() < initial_len { | ||
HttpResponse::Ok().json(json!({ "message": "Policy deleted successfully", "id": id })) | ||
} else { | ||
HttpResponse::NotFound().json(json!({ "error": "Policy not found", "id": id })) | ||
} | ||
} | ||
|
||
/// Handler for `GET /api/security/protected` | ||
/// | ||
/// A protected endpoint for demonstration purposes. | ||
pub async fn protected_endpoint() -> impl Responder { | ||
HttpResponse::Ok().body("This is a protected endpoint!") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,41 @@ | ||
//! REST API Module for Flusso | ||
//! | ||
//! This module handles all REST endpoints for the backend, exposing data | ||
//! for the frontend and other clients. | ||
use actix_cors::Cors; | ||
use actix_web::{App, HttpServer}; | ||
use actix_web::web::{Data, ServiceConfig}; | ||
use std::sync::Mutex; | ||
use kube::Client; // Importa el cliente de Kubernetes | ||
|
||
pub mod routes; // Declarar submódulo de rutas | ||
pub mod handlers; // Declarar submódulo de handlers | ||
|
||
use crate::rest::routes::configure_routes; | ||
use crate::backends::handlers::AppState as BackendsState; | ||
use crate::security::handlers::AppState as SecurityState; | ||
use crate::observability::handlers::ObservabilityState; | ||
|
||
/// Starts the REST API server. | ||
/// | ||
/// # Arguments | ||
/// - `port`: Port number for the REST server. | ||
/// | ||
/// # Returns | ||
/// A `Result` indicating whether the server started successfully. | ||
pub async fn start_rest_server(port: u16) -> std::io::Result<()> { | ||
pub async fn start_rest_server(port: u16, client: Client) -> std::io::Result<()> { | ||
println!("Starting REST server on port {}", port); | ||
|
||
HttpServer::new(move || { | ||
// Configura el middleware CORS dentro del closure | ||
let cors = Cors::default() | ||
.allow_any_origin() // Permite cualquier origen; cambia esto en producción | ||
.allow_any_header() | ||
.allow_any_method(); | ||
let backends_state = Data::new(BackendsState { | ||
backends: Mutex::new(vec![]), | ||
}); | ||
|
||
let security_state = Data::new(SecurityState { | ||
policies: Mutex::new(vec![]), | ||
}); | ||
|
||
let observability_state = Data::new(ObservabilityState::new()); // Usa el método new() | ||
|
||
// Si necesitas usar el cliente `client` en el futuro, puedes incluirlo aquí. | ||
|
||
HttpServer::new(move || { | ||
App::new() | ||
.wrap(cors) // Aplica CORS al App | ||
.configure(configure_routes) // Registra las rutas | ||
.app_data(backends_state.clone()) | ||
.app_data(security_state.clone()) | ||
.app_data(observability_state.clone()) | ||
// Puedes registrar el cliente como parte del estado compartido si es necesario. | ||
.app_data(Data::new(client.clone())) | ||
.configure(|cfg: &mut ServiceConfig| configure_routes(cfg)) | ||
}) | ||
.bind(("0.0.0.0", port))? | ||
.run() | ||
.await | ||
} | ||
|
||
pub mod handlers; | ||
pub mod routes; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,35 @@ | ||
//! Route configuration for the REST API | ||
//src/rest/routes.rs | ||
|
||
use actix_web::web; | ||
use crate::rest::handlers; | ||
use crate::rest::handlers::{get_backends, add_backend, delete_backend}; | ||
use crate::gateway::handlers::{list_gateways, add_gateway, delete_gateway, configure_tls, get_gateway_metrics}; | ||
use crate::observability::handlers::{get_metrics, get_logs, export_prometheus_metrics}; // Importa handlers correctos | ||
use crate::security::handlers::{list_policies, add_policy, delete_policy, protected_endpoint}; | ||
|
||
/// Configures the REST API routes. | ||
/// | ||
/// This function is used to register all the available endpoints for the REST API. | ||
pub fn configure_routes(cfg: &mut web::ServiceConfig) { | ||
cfg.service( | ||
web::scope("/api") | ||
.route("/metrics", web::get().to(handlers::get_metrics)) // GET /api/metrics | ||
.route("/alerts", web::get().to(handlers::get_alerts)) // GET /api/alerts | ||
.route("/backends", web::get().to(handlers::get_backends)) // GET /api/backends | ||
.route("/backends", web::post().to(handlers::add_backend)) // POST /api/backends | ||
.route("/backends/{id}", web::delete().to(handlers::delete_backend)), // DELETE /api/backends/{id} | ||
.route("/metrics", web::get().to(get_metrics)) // GET /api/metrics | ||
.route("/logs", web::get().to(get_logs)) // GET /api/logs | ||
.route("/metrics/export", web::get().to(export_prometheus_metrics)) // GET /api/metrics/export | ||
|
||
// Backends | ||
.route("/backends", web::get().to(get_backends)) // GET /api/backends | ||
.route("/backends", web::post().to(add_backend)) // POST /api/backends | ||
.route("/backends/{id}", web::delete().to(delete_backend)) // DELETE /api/backends/{id} | ||
|
||
// Gateways | ||
.route("/gateways", web::get().to(list_gateways)) // GET /api/gateways | ||
.route("/gateways", web::post().to(add_gateway)) // POST /api/gateways | ||
.route("/gateways/{id}", web::delete().to(delete_gateway)) // DELETE /api/gateways/{id} | ||
.route("/gateways/tls", web::post().to(configure_tls)) // POST /api/gateways/tls | ||
.route("/gateways/metrics", web::get().to(get_gateway_metrics)) // GET /api/gateways/metrics | ||
|
||
// Security | ||
.route("/security/policies", web::get().to(list_policies)) // GET /api/security/policies | ||
.route("/security/policies", web::post().to(add_policy)) // POST /api/security/policies | ||
.route("/security/policies/{id}", web::delete().to(delete_policy)) // DELETE /api/security/policies/{id} | ||
.route("/security/protected", web::get().to(protected_endpoint)), // GET /api/security/protected | ||
); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
// src/security/mod.rs | ||
pub mod handlers; | ||
pub mod routes; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
// src/security/routes.rs | ||
use actix_web::web; | ||
use super::handlers; | ||
|
||
|
Oops, something went wrong.