zones.rs 1.35 KB
Newer Older
Gaël Berthaud-Müller's avatar
Gaël Berthaud-Müller committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
use rocket::State;
use rocket::http::Status;

use rocket_contrib::json::Json;

use trust_dns_client::client::{Client};
use trust_dns_client::op::{DnsResponse, ResponseCode};
use trust_dns_client::rr::{DNSClass, Name, RecordType};

use crate::models::dns;
use crate::models::errors::ErrorResponse;
use crate::models::users::UserInfo;
use crate::DnsClient;


#[get("/zones/<zone>/records")]
pub fn get_zone_records(
    client: State<DnsClient>,
    _user_info: UserInfo,
    zone: String
) -> Result<Json<Vec<dns::Record>>, ErrorResponse<()>> {

    // TODO: Implement FromParam for Name
    let name = Name::from_utf8(&zone).unwrap();

    let response: DnsResponse = client.query(&name, DNSClass::IN, RecordType::AXFR).unwrap();

    if response.response_code() != ResponseCode::NoError {
        return ErrorResponse::new(
            Status::NotFound,
            format!("zone {} could not be found", name.to_utf8())
        ).err()
    }

    let answers = response.answers();
    let mut records: Vec<_> = answers.to_vec().into_iter()
        .map(|record| dns::Record::from(record))
        .filter(|record| match record.rdata {
            dns::RData::NULL { .. } | dns::RData::DNSSEC(_) => false,
            _ => true,
        }).collect();

    // AXFR response ends with SOA, we remove it so it is not doubled in the response.
    records.pop();

    Ok(Json(records))
}