Skip to main content

dnslib/control_plane/
transfer.rs

1//! Zone transfer orchestration between configured servers.
2
3use serde_json::Value;
4
5use crate::{
6    control_plane::config::{AppConfig, DnsServerConfig},
7    core::error::{Error, Result},
8    vendors::runtime::VendorClient,
9};
10
11#[derive(Debug, Clone, serde::Serialize)]
12pub struct ZoneTransferResult {
13    pub zone: String,
14    pub from: String,
15    pub to: String,
16    pub bytes: usize,
17    pub import_result: Value,
18}
19
20pub async fn transfer_zone(
21    app_config: Option<&AppConfig>,
22    zone: &str,
23    from_id: &str,
24    to_id: &str,
25    overwrite: bool,
26    overwrite_zone: bool,
27) -> Result<ZoneTransferResult> {
28    let Some(cfg) = app_config else {
29        return Err(Error::parse(
30            "zone transfer requires a config file with --from and --to server entries",
31        ));
32    };
33
34    let from_server = cfg.selected_server(Some(from_id))?;
35    let to_server = cfg.selected_server(Some(to_id))?;
36
37    let zone_file = server_export_zone(from_server, zone).await?;
38    let bytes = zone_file.len();
39    let file_name = format!("{zone}.txt");
40    let import_result = server_import_zone(
41        to_server,
42        zone,
43        file_name,
44        zone_file.into_bytes(),
45        overwrite,
46        overwrite_zone,
47    )
48    .await?;
49
50    Ok(ZoneTransferResult {
51        zone: zone.to_string(),
52        from: from_id.to_string(),
53        to: to_id.to_string(),
54        bytes,
55        import_result,
56    })
57}
58
59async fn server_export_zone(server: &DnsServerConfig, zone: &str) -> Result<String> {
60    VendorClient::export_zone_for_server(server, zone).await
61}
62
63async fn server_import_zone(
64    server: &DnsServerConfig,
65    zone: &str,
66    file_name: String,
67    file_bytes: Vec<u8>,
68    overwrite: bool,
69    overwrite_zone: bool,
70) -> Result<Value> {
71    VendorClient::import_zone_for_server(
72        server,
73        zone,
74        file_name,
75        file_bytes,
76        overwrite,
77        overwrite_zone,
78    )
79    .await
80}