use crate::config::ResolvedServer;
pub fn to_terraform_json(servers: &[&ResolvedServer]) -> String {
let items: Vec<serde_json::Value> = servers
.iter()
.map(|s| {
serde_json::json!({
"name": s.name,
"host": s.host,
"user": s.user,
"port": s.port,
"ssh_key": s.ssh_key,
"group": s.group_name,
"env": s.env_name,
"namespace": s.namespace,
"tags": s.tags,
})
})
.collect();
let root = serde_json::json!({ "servers": items });
match serde_json::to_string_pretty(&root) {
Ok(s) => s + "\n",
Err(e) => {
eprintln!("Erreur sérialisation JSON Terraform : {e}");
std::process::exit(1);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::{ConnectionMode, ResolvedServer};
fn make_server(name: &str, host: &str, group: &str) -> ResolvedServer {
ResolvedServer {
namespace: String::new(),
group_name: group.to_string(),
env_name: String::new(),
name: name.to_string(),
host: host.to_string(),
user: "admin".to_string(),
port: 22,
ssh_key: "~/.ssh/id_rsa".to_string(),
ssh_cert: String::new(),
ssh_agent_sock: String::new(),
ssh_options: vec![],
default_mode: ConnectionMode::Direct,
jump_host: None,
bastion_host: None,
bastion_user: None,
bastion_template: String::new(),
use_system_ssh_config: false,
probe_filesystems: vec![],
tunnels: vec![],
tags: vec!["web".to_string()],
control_master: false,
agent_forwarding: false,
control_path: String::new(),
control_persist: "10m".to_string(),
pre_connect_hook: None,
post_disconnect_hook: None,
hook_timeout_secs: 5,
wallix_group: None,
wallix_account: "default".to_string(),
wallix_protocol: "SSH".to_string(),
wallix_auto_select: true,
wallix_fail_if_menu_match_error: true,
wallix_selection_timeout_secs: 8,
wallix_direct: false,
wallix_authorization: None,
wallix_header_columns: vec![],
notes: String::new(),
}
}
#[test]
fn empty_produces_empty_servers_array() {
let json = to_terraform_json(&[]);
let v: serde_json::Value = serde_json::from_str(&json).unwrap();
assert_eq!(v["servers"].as_array().unwrap().len(), 0);
}
#[test]
fn single_server_fields() {
let srv = make_server("web-01", "198.51.100.1", "prod");
let json = to_terraform_json(&[&srv]);
let v: serde_json::Value = serde_json::from_str(&json).unwrap();
let s = &v["servers"][0];
assert_eq!(s["name"], "web-01");
assert_eq!(s["host"], "198.51.100.1");
assert_eq!(s["user"], "admin");
assert_eq!(s["port"], 22);
assert_eq!(s["group"], "prod");
assert_eq!(s["tags"][0], "web");
}
#[test]
fn multiple_servers_all_present() {
let s1 = make_server("alpha", "10.0.0.1", "g1");
let s2 = make_server("beta", "10.0.0.2", "g2");
let json = to_terraform_json(&[&s1, &s2]);
let v: serde_json::Value = serde_json::from_str(&json).unwrap();
assert_eq!(v["servers"].as_array().unwrap().len(), 2);
assert_eq!(v["servers"][0]["name"], "alpha");
assert_eq!(v["servers"][1]["name"], "beta");
}
#[test]
fn ssh_key_field_included() {
let mut srv = make_server("key-srv", "10.0.0.3", "g");
srv.ssh_key = "~/.ssh/prod_ed25519".into();
let json = to_terraform_json(&[&srv]);
let v: serde_json::Value = serde_json::from_str(&json).unwrap();
assert_eq!(v["servers"][0]["ssh_key"], "~/.ssh/prod_ed25519");
}
#[test]
fn namespace_field_included() {
let mut srv = make_server("ns-srv", "10.0.0.4", "g");
srv.namespace = "MyNS".into();
let json = to_terraform_json(&[&srv]);
let v: serde_json::Value = serde_json::from_str(&json).unwrap();
assert_eq!(v["servers"][0]["namespace"], "MyNS");
}
#[test]
fn env_field_included() {
let mut srv = make_server("env-srv", "10.0.0.5", "g");
srv.env_name = "staging".into();
let json = to_terraform_json(&[&srv]);
let v: serde_json::Value = serde_json::from_str(&json).unwrap();
assert_eq!(v["servers"][0]["env"], "staging");
}
#[test]
fn output_ends_with_newline() {
let srv = make_server("nl", "10.0.0.6", "g");
let json = to_terraform_json(&[&srv]);
assert!(json.ends_with('\n'));
}
}