feat(matilda): administración de servidores — core + config + plan
matilda-core: modelo declarativo (Host, Container, VHost, Inventory). matilda-config: renderiza Container→docker-compose/docker run y VHost→bloque server nginx (con TLS + redirección :80→:443). matilda-plan: reconciliación pura actual→deseado con acciones ordenadas por dependencia (contenedores antes que vhosts, removes en orden inverso). Demo CLI en apps/matilda. 29 tests. Funciones puras, cero Docker/SSH/disco. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
//! `matilda-config` — del modelo declarativo a archivos de configuración.
|
||||
//!
|
||||
//! Funciones puras: toman un tipo de `matilda-core` y devuelven el texto
|
||||
//! de configuración listo para escribir en el servidor. No tocan disco
|
||||
//! ni Docker — sólo construyen strings, así que cada salida es testeable
|
||||
//! y determinista.
|
||||
//!
|
||||
//! - [`docker`] — `Container` → `docker run` / servicio docker-compose.
|
||||
//! - [`nginx`] — `VHost` → bloque `server` de nginx.
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
pub mod docker;
|
||||
pub mod nginx;
|
||||
|
||||
pub use docker::{compose_service, docker_run_command};
|
||||
pub use nginx::nginx_server_block;
|
||||
|
||||
use matilda_core::Inventory;
|
||||
|
||||
/// Renderiza el `docker-compose.yml` completo de un inventario.
|
||||
pub fn compose_file(inv: &Inventory) -> String {
|
||||
let mut out = String::from("services:\n");
|
||||
for c in inv.containers() {
|
||||
out.push_str(&compose_service(c));
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// Renderiza el archivo de sites de nginx — un bloque `server` por
|
||||
/// vhost, separados por una línea en blanco.
|
||||
pub fn nginx_sites(inv: &Inventory) -> String {
|
||||
inv.vhosts()
|
||||
.map(nginx_server_block)
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use matilda_core::{Container, VHost};
|
||||
|
||||
#[test]
|
||||
fn compose_file_lists_every_container() {
|
||||
let mut inv = Inventory::new();
|
||||
inv.add_container(Container::new("web", "nginx"));
|
||||
inv.add_container(Container::new("db", "postgres:16"));
|
||||
let yaml = compose_file(&inv);
|
||||
assert!(yaml.starts_with("services:\n"));
|
||||
assert!(yaml.contains(" web:\n") && yaml.contains(" db:\n"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nginx_sites_renders_every_vhost() {
|
||||
let mut inv = Inventory::new();
|
||||
inv.add_vhost(VHost::to_container("a.com", "web", 80));
|
||||
inv.add_vhost(VHost::to_container("b.com", "web", 80));
|
||||
let conf = nginx_sites(&inv);
|
||||
assert!(conf.contains("server_name a.com;"));
|
||||
assert!(conf.contains("server_name b.com;"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user