prvng_platform/crates/orchestrator/src/router.rs

147 lines
6.4 KiB
Rust

use axum::{
routing::{delete, get, post},
Router,
};
use provisioning_orchestrator::{compliance_routes, webhooks::{handle_webhook, WebhookState, WorkspaceRegistry}};
use std::sync::Arc;
use tower_http::cors::CorsLayer;
use crate::{
api_catalog,
handlers::{
audit::{
apply_audit_retention, export_audit_logs, get_audit_stats, get_audit_storage_stats,
query_audit_logs, search_audit_logs,
},
batch::{
cancel_batch_operation, execute_batch_operation, get_batch_operation_status,
list_batch_operations,
},
extensions::{
get_services_status, list_dns_records, list_loaded_extensions, list_oci_artifacts,
list_services, reload_extension,
},
rollback::{
create_checkpoint, execute_rollback, get_checkpoint, get_rollback_statistics,
list_checkpoints, restore_from_checkpoint,
},
state::{
get_state_statistics, get_system_health, get_system_metrics, get_workflow_progress,
get_workflow_snapshots,
},
tasks::{get_task_status, health_check, list_tasks},
test_env::{
cleanup_test_environment, create_test_environment, get_environment_logs,
get_test_environment, list_test_environments, run_environment_tests,
},
vm_pool::{destroy_runner, get_p95, record_build_metrics, spawn_runner},
workflows::{
create_cluster_workflow, create_component_workflow, create_server_workflow,
create_taskserv_workflow,
},
},
};
pub fn build_router(state: Arc<provisioning_orchestrator::AppState>) -> Router {
let webhook_state = Arc::new(WebhookState {
registry: Arc::new(parking_lot::RwLock::new(WorkspaceRegistry::new())),
});
let app = Router::new()
.route("/api/v1/catalog", get(api_catalog::api_catalog))
.route("/health", get(health_check))
.route("/api/v1/health", get(health_check))
.route("/tasks", get(list_tasks))
.route("/tasks/{id}", get(get_task_status))
.route("/workflows/servers/create", post(create_server_workflow))
.route("/workflows/taskserv/create", post(create_taskserv_workflow))
.route("/workflows/cluster/create", post(create_cluster_workflow))
.route(
"/api/v1/workflows/component/{operation}",
post(create_component_workflow),
)
// Batch operation routes
.route("/batch/execute", post(execute_batch_operation))
.route("/batch/operations", get(list_batch_operations))
.route("/batch/operations/{id}", get(get_batch_operation_status))
.route(
"/batch/operations/{id}/cancel",
post(cancel_batch_operation),
)
// State management routes
.route("/state/workflows/{id}/progress", get(get_workflow_progress))
.route(
"/state/workflows/{id}/snapshots",
get(get_workflow_snapshots),
)
.route("/state/system/metrics", get(get_system_metrics))
.route("/state/system/health", get(get_system_health))
.route("/state/statistics", get(get_state_statistics))
// Rollback and recovery routes
.route("/rollback/checkpoints", post(create_checkpoint))
.route("/rollback/checkpoints", get(list_checkpoints))
.route("/rollback/checkpoints/{id}", get(get_checkpoint))
.route("/rollback/execute", post(execute_rollback))
.route("/rollback/restore/{id}", post(restore_from_checkpoint))
.route("/rollback/statistics", get(get_rollback_statistics))
// Test environment routes
.route("/test/environments/create", post(create_test_environment))
.route("/test/environments", get(list_test_environments))
.route("/test/environments/{id}", get(get_test_environment))
.route("/test/environments/{id}/run", post(run_environment_tests))
.route(
"/test/environments/{id}",
axum::routing::delete(cleanup_test_environment),
)
.route("/test/environments/{id}/logs", get(get_environment_logs))
// DNS integration routes
.route("/api/v1/dns/records", get(list_dns_records))
// Extension loading routes
.route("/api/v1/extensions/loaded", get(list_loaded_extensions))
.route("/api/v1/extensions/reload", post(reload_extension))
// OCI registry routes
.route("/api/v1/oci/artifacts", post(list_oci_artifacts))
// Service orchestration routes
.route("/api/v1/services/list", get(list_services))
.route("/api/v1/services/status", get(get_services_status))
// VM pool routes (ephemeral buildkit runners — ADR-039)
.route("/api/v1/vm-pool/spawn", post(spawn_runner))
.route("/api/v1/vm-pool/{lease_id}", delete(destroy_runner))
.route("/api/v1/vm-pool/p95/{workspace}", get(get_p95))
.route("/api/v1/vm-pool/metrics", post(record_build_metrics))
// Audit logging routes
.route("/api/v1/audit/query", post(query_audit_logs))
.route("/api/v1/audit/export", post(export_audit_logs))
.route("/api/v1/audit/stats", get(get_audit_stats))
.route("/api/v1/audit/storage-stats", get(get_audit_storage_stats))
.route("/api/v1/audit/apply-retention", post(apply_audit_retention))
.route("/api/v1/audit/search", post(search_audit_logs))
// Compliance routes
.nest(
"/api/v1/compliance",
compliance_routes(state.compliance_service.clone()),
)
// Merge monitoring routes (includes /metrics, /ws, /events)
.merge(state.monitoring_system.create_routes())
// Webhook handler (separate state — workspace registry)
.route(
"/api/v1/webhooks/{workspace_id}",
post(handle_webhook).with_state(webhook_state),
)
.layer(CorsLayer::permissive())
.with_state(state.clone());
// Infra reconcile endpoint — only compiled when the `nats` feature is active.
// Must be registered on a fresh router that still holds a state reference.
#[cfg(feature = "nats")]
let app = {
use crate::handlers::infra::trigger_infra_reconcile;
app.merge(
Router::new()
.route("/api/v1/infra/reconcile", post(trigger_infra_reconcile))
.with_state(state),
)
};
app
}