- Migration 0007: ALTER TABLE networks ADD COLUMN name TEXT NOT NULL DEFAULT '' - Network model, repository, and API updated to include name - Networks page: name input in the add form, Name column as first column in table - Delete modal now shows "Name (CIDR)" for clarity - Hosts page: network dropdowns now show network name instead of CIDR - Seeds updated with names (LAN, DMZ, Corporate, VPN) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
145 lines
6.1 KiB
Rust
145 lines
6.1 KiB
Rust
// models.rs — Shared data models (server + client)
|
||
//
|
||
// This module defines the structs that represent the IPAM domain entities.
|
||
// They are compiled for both the server and WASM, because Leptos needs them
|
||
// on both sides:
|
||
// - Server : to read/write the database and render HTML
|
||
// - Client : to display data inside Leptos components
|
||
//
|
||
// Each struct derives `Serialize` and `Deserialize` from serde.
|
||
// This is required for Leptos to transfer data between the server and the
|
||
// browser through server functions (#[server]).
|
||
|
||
use serde::{Deserialize, Serialize};
|
||
|
||
// ─── Network ──────────────────────────────────────────────────────────────────
|
||
|
||
/// An IP network defined by its CIDR range.
|
||
///
|
||
/// Example: { id: 1, cidr: "192.168.1.0/24" }
|
||
/// → covers 192.168.1.0 to 192.168.1.255 (254 usable hosts)
|
||
///
|
||
/// CIDR (Classless Inter-Domain Routing) combines the network address and
|
||
/// the subnet mask into a single field: <address>/<prefix length>.
|
||
/// /24 = 24-bit mask = 255.255.255.0
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct Network {
|
||
/// Unique identifier, auto-incremented by the database.
|
||
/// `i64` is a signed 64-bit integer — maps to `BIGINT` in SQL.
|
||
pub id: i64,
|
||
|
||
/// Human-readable name. Examples: "LAN", "DMZ", "VPN"
|
||
pub name: String,
|
||
|
||
/// Address range in CIDR notation.
|
||
/// Examples: "10.0.0.0/8", "172.16.0.0/12", "192.168.1.0/24"
|
||
pub cidr: String,
|
||
}
|
||
|
||
// ─── Host ─────────────────────────────────────────────────────────────────────
|
||
|
||
/// A host (server, workstation, network device) belonging to a network.
|
||
///
|
||
/// Constraint: the IP address must fall within the CIDR range of the network
|
||
/// referenced by `network_id`. This is enforced on creation and update.
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct Host {
|
||
pub id: i64,
|
||
|
||
/// Human-readable name. Examples: "web-server-01", "main-router"
|
||
pub name: String,
|
||
|
||
/// IPv4 address stored as text. Example: "192.168.1.10"
|
||
/// We use String instead of IpAddr to simplify serialization
|
||
/// and database storage.
|
||
pub ip: String,
|
||
|
||
/// Foreign key referencing the network this host belongs to.
|
||
pub network_id: i64,
|
||
}
|
||
|
||
// ─── Port ─────────────────────────────────────────────────────────────────────
|
||
|
||
/// A network port entry in the global port catalog.
|
||
///
|
||
/// Ports are defined once here; host_ports and application_ports link them
|
||
/// to hosts and applications through separate join tables.
|
||
/// Well-known ports (0–1023) have standardized protocol assignments.
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct Port {
|
||
/// TCP/UDP port number (0–65535).
|
||
/// `u16` is an unsigned 16-bit integer — the exact range for port numbers.
|
||
pub number: u16,
|
||
|
||
/// Description of the protocol typically running on this port.
|
||
/// `Option<String>`: absent (None) when the protocol is unknown.
|
||
/// Examples: Some("SSH"), Some("HTTPS"), None
|
||
pub description: Option<String>,
|
||
}
|
||
|
||
// ─── HostPort ─────────────────────────────────────────────────────────────────
|
||
|
||
/// Join record representing a port open on a specific host.
|
||
///
|
||
/// Maps to the `host_ports` table (many-to-many between hosts and ports).
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct HostPort {
|
||
pub host_id: i64,
|
||
pub port_number: u16,
|
||
}
|
||
|
||
impl Port {
|
||
/// Returns the standard description for common well-known ports.
|
||
/// Used to pre-fill the description field when adding a port.
|
||
///
|
||
/// `match` is Rust's exhaustive pattern-matching construct (like switch/case,
|
||
/// but the compiler enforces that all cases are handled).
|
||
pub fn known_protocol(number: u16) -> Option<&'static str> {
|
||
// `&'static str`: a reference to a string that lives for the entire
|
||
// program lifetime (string literals are stored in the compiled binary).
|
||
match number {
|
||
21 => Some("FTP"),
|
||
22 => Some("SSH"),
|
||
23 => Some("Telnet"),
|
||
25 => Some("SMTP"),
|
||
53 => Some("DNS"),
|
||
80 => Some("HTTP"),
|
||
110 => Some("POP3"),
|
||
143 => Some("IMAP"),
|
||
443 => Some("HTTPS"),
|
||
3306 => Some("MySQL"),
|
||
5432 => Some("PostgreSQL"),
|
||
6379 => Some("Redis"),
|
||
8080 => Some("HTTP (alternate)"),
|
||
_ => None, // `_` is the wildcard pattern — matches everything else
|
||
}
|
||
}
|
||
}
|
||
|
||
// ─── Application ──────────────────────────────────────────────────────────────
|
||
|
||
/// An application that uses one or more ports.
|
||
///
|
||
/// The association between an application and a port is non-strict:
|
||
/// the same port can be shared by multiple applications.
|
||
/// Example: port 80 might be used by both Nginx and an application proxy.
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct Application {
|
||
pub id: i64,
|
||
|
||
/// Application name. Examples: "Nginx", "PostgreSQL", "Prometheus"
|
||
pub name: String,
|
||
}
|
||
|
||
// ─── ApplicationPort ──────────────────────────────────────────────────────────
|
||
|
||
/// Join record linking an application to a port (many-to-many relationship).
|
||
///
|
||
/// A dedicated struct is used instead of Vec<Port> inside Application
|
||
/// so it maps directly to the join table in the database.
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct ApplicationPort {
|
||
pub application_id: i64,
|
||
pub port_number: u16,
|
||
}
|