78 lines
2.4 KiB
Rust
78 lines
2.4 KiB
Rust
use crate::allocator::{find_next_subnet, usable_host_count};
|
|
use crate::models::Pool;
|
|
use crate::state::AppState;
|
|
use crate::templates::PoolPreviewTemplate;
|
|
use askama::Template;
|
|
use axum::extract::{Path, Query, State};
|
|
use axum::response::{Html, IntoResponse};
|
|
use serde::Deserialize;
|
|
use tracing::error;
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct PreviewQuery {
|
|
pub prefix_length: i32,
|
|
}
|
|
|
|
pub async fn pool_preview(
|
|
State(state): State<AppState>,
|
|
Path(slug): Path<String>,
|
|
Query(q): Query<PreviewQuery>,
|
|
) -> impl IntoResponse {
|
|
let pool: Option<Pool> = sqlx::query_as("SELECT * FROM pools WHERE slug = ? AND enabled = true")
|
|
.bind(&slug)
|
|
.fetch_optional(&state.pool)
|
|
.await
|
|
.unwrap_or_default();
|
|
|
|
let pool = match pool {
|
|
Some(p) => p,
|
|
None => {
|
|
let template = PoolPreviewTemplate {
|
|
cidr: String::new(),
|
|
prefix_length: q.prefix_length,
|
|
address_count: 0,
|
|
usable_host_count: 0,
|
|
has_error: true,
|
|
error: "Pool does not exist.".to_string(),
|
|
};
|
|
return Html(template.render().unwrap_or_default());
|
|
}
|
|
};
|
|
|
|
let active: Vec<String> = sqlx::query_scalar(
|
|
"SELECT cidr FROM allocations WHERE pool_id = ? AND status IN ('active', 'reserved')",
|
|
)
|
|
.bind(pool.id)
|
|
.fetch_all(&state.pool)
|
|
.await
|
|
.unwrap_or_default();
|
|
|
|
let allowed = pool.allowed_prefixes();
|
|
|
|
let template = match find_next_subnet(&pool.cidr, q.prefix_length, &allowed, &active) {
|
|
Ok(info) => PoolPreviewTemplate {
|
|
cidr: info.cidr,
|
|
prefix_length: info.prefix_length,
|
|
address_count: info.address_count,
|
|
usable_host_count: info.usable_host_count,
|
|
has_error: false,
|
|
error: String::new(),
|
|
},
|
|
Err(e) => PoolPreviewTemplate {
|
|
cidr: String::new(),
|
|
prefix_length: q.prefix_length,
|
|
address_count: usable_host_count(q.prefix_length),
|
|
usable_host_count: usable_host_count(q.prefix_length),
|
|
has_error: true,
|
|
error: e.to_string(),
|
|
},
|
|
};
|
|
|
|
match template.render() {
|
|
Ok(html) => Html(html),
|
|
Err(e) => {
|
|
error!("Preview template render error: {}", e);
|
|
Html("Preview error.".to_string())
|
|
}
|
|
}
|
|
}
|