dnsync 0.2.2

DNS Sync and Control with MCP
Documentation
use rmcp::{ErrorData as McpError, model::*};

use crate::{
    control_plane::policy::Policy,
    core::dns::service::DnsService,
    core::dns::zones,
    mcp::{
        helpers::{run_json, run_text},
        params::*,
    },
};

pub async fn handle_list_zones<C: DnsService + Send + Sync>(
    client: &C,
    policy: &Policy,
    p: ListZonesParams,
) -> Result<CallToolResult, McpError> {
    Ok(run_json(
        "dns_list_zones",
        policy.check_read(),
        zones::list_zones(
            client,
            p.page_number.unwrap_or(1),
            p.zones_per_page.unwrap_or(50),
        ),
    )
    .await)
}

pub async fn handle_create_zone<C: DnsService + Send + Sync>(
    client: &C,
    policy: &Policy,
    p: CreateZoneParams,
) -> Result<CallToolResult, McpError> {
    Ok(run_json(
        "dns_create_zone",
        policy.check_write().and(policy.check_zone(&p.zone)),
        zones::create_zone(client, &p.zone, &p.zone_type),
    )
    .await)
}

pub async fn handle_delete_zone<C: DnsService + Send + Sync>(
    client: &C,
    policy: &Policy,
    p: ZoneParams,
) -> Result<CallToolResult, McpError> {
    Ok(run_json(
        "dns_delete_zone",
        policy.check_delete().and(policy.check_zone(&p.zone)),
        zones::delete_zone(client, &p.zone),
    )
    .await)
}

pub async fn handle_enable_zone<C: DnsService + Send + Sync>(
    client: &C,
    policy: &Policy,
    p: ZoneParams,
) -> Result<CallToolResult, McpError> {
    Ok(run_json(
        "dns_enable_zone",
        policy.check_write().and(policy.check_zone(&p.zone)),
        zones::enable_zone(client, &p.zone),
    )
    .await)
}

pub async fn handle_disable_zone<C: DnsService + Send + Sync>(
    client: &C,
    policy: &Policy,
    p: ZoneParams,
) -> Result<CallToolResult, McpError> {
    Ok(run_json(
        "dns_disable_zone",
        policy.check_write().and(policy.check_zone(&p.zone)),
        zones::disable_zone(client, &p.zone),
    )
    .await)
}

pub async fn handle_import_zone_file<C: DnsService + Send + Sync>(
    client: &C,
    policy: &Policy,
    p: ImportZoneFileParams,
) -> Result<CallToolResult, McpError> {
    let file_name = p.file_name.unwrap_or_else(|| format!("{}.txt", p.zone));
    Ok(run_json(
        "dns_import_zone_file",
        policy.check_write().and(policy.check_zone(&p.zone)),
        zones::import_zone_file(
            client,
            &p.zone,
            file_name,
            p.content.into_bytes(),
            p.options.overwrite,
            p.options.overwrite_zone,
            p.options.overwrite_soa_serial,
        ),
    )
    .await)
}

pub async fn handle_export_zone_file<C: DnsService + Send + Sync>(
    client: &C,
    policy: &Policy,
    p: ExportZoneFileParams,
) -> Result<CallToolResult, McpError> {
    Ok(run_text(
        "dns_export_zone_file",
        policy.check_read().and(policy.check_zone(&p.zone)),
        zones::export_zone_file(client, &p.zone),
    )
    .await)
}