dnslib/control_plane/
transfer.rs1use 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}