48 lines
1.4 KiB
Rust
48 lines
1.4 KiB
Rust
|
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))
|
||
|
}
|