move record list conversion to models module
This commit is contained in:
parent
96f66e1fd7
commit
77cc634257
6 changed files with 67 additions and 30 deletions
|
@ -130,6 +130,20 @@ impl From<DnsApiError> for ErrorResponse {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<models::RecordListParseError> for ErrorResponse {
|
||||
fn from(e: models::RecordListParseError) -> Self {
|
||||
models::ErrorResponse::new(
|
||||
Status::BadRequest,
|
||||
"Record list contains records that could not be parsed into DNS records".into()
|
||||
).with_details(
|
||||
json!({
|
||||
"zone_name": e.zone.to_utf8(),
|
||||
"records": e.bad_records
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<S> From<ErrorResponse> for Outcome<S, ErrorResponse> {
|
||||
fn from(e: ErrorResponse) -> Self {
|
||||
|
|
|
@ -15,5 +15,5 @@ pub use errors::{UserError, ErrorResponse, make_500};
|
|||
pub use name::{AbsoluteName, SerdeName};
|
||||
pub use user::{LocalUser, UserInfo, Role, UserZone, User, CreateUserRequest};
|
||||
pub use rdata::RData;
|
||||
pub use record::Record;
|
||||
pub use record::{Record, RecordList, ParseRecordList, RecordListParseError};
|
||||
pub use zone::{Zone, AddZoneMemberRequest, CreateZoneRequest};
|
|
@ -69,4 +69,10 @@ impl Deref for AbsoluteName {
|
|||
fn deref(&self) -> &Self::Target {
|
||||
&self.0.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AbsoluteName {
|
||||
pub fn into_inner(self) -> Name {
|
||||
self.0.0
|
||||
}
|
||||
}
|
|
@ -247,7 +247,7 @@ impl TryFrom<RData> for dns::RData {
|
|||
// TODO: Error out for DNSSEC? Prefer downstream checks?
|
||||
RData::DNSSEC(_) => todo!(),
|
||||
// TODO: Disallow unknown? (could be used to bypass unsopported types?) Prefer downstream checks?
|
||||
RData::Unknown { code, data } => todo!(),
|
||||
RData::Unknown { code: _code, data: _data } => todo!(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,4 +40,41 @@ impl TryFrom<Record> for dns::Record {
|
|||
trust_dns_record.set_dns_class(record.dns_class.into());
|
||||
Ok(trust_dns_record)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub type RecordList = Vec<Record>;
|
||||
|
||||
pub struct RecordListParseError {
|
||||
pub bad_records: Vec<Record>,
|
||||
pub zone: dns::Name,
|
||||
}
|
||||
|
||||
pub trait ParseRecordList {
|
||||
fn try_into_dns_type(self, zone: dns::Name) -> Result<Vec<dns::Record>, RecordListParseError>;
|
||||
}
|
||||
|
||||
impl ParseRecordList for RecordList {
|
||||
fn try_into_dns_type(self, zone: dns::Name) -> Result<Vec<dns::Record>, RecordListParseError> {
|
||||
// TODO: What about relative names (also in cnames and stuff)
|
||||
let mut bad_records = Vec::new();
|
||||
let mut records: Vec<dns::Record> = Vec::new();
|
||||
|
||||
for record in self.into_iter() {
|
||||
let this_record = record.clone();
|
||||
if let Ok(record) = record.try_into() {
|
||||
records.push(record);
|
||||
} else {
|
||||
bad_records.push(this_record.clone());
|
||||
}
|
||||
}
|
||||
|
||||
if !bad_records.is_empty() {
|
||||
return Err(RecordListParseError {
|
||||
zone,
|
||||
bad_records,
|
||||
});
|
||||
}
|
||||
return Ok(records)
|
||||
}
|
||||
}
|
|
@ -1,14 +1,13 @@
|
|||
use std::convert::TryInto;
|
||||
use serde_json::json;
|
||||
use rocket::Response;
|
||||
use rocket::http::Status;
|
||||
|
||||
use rocket_contrib::json::Json;
|
||||
|
||||
use crate::DbConn;
|
||||
use crate::models;
|
||||
use crate::dns;
|
||||
use crate::models;
|
||||
use crate::dns::{RecordApi, ZoneApi};
|
||||
use crate::models::{ParseRecordList};
|
||||
|
||||
|
||||
#[get("/zones/<zone>/records")]
|
||||
|
@ -58,33 +57,14 @@ pub async fn create_zone_records(
|
|||
}
|
||||
}).await?;
|
||||
|
||||
// TODO: What about relative names (also in cnames and stuff)
|
||||
let mut bad_records = Vec::new();
|
||||
let mut records: Vec<dns::Record> = Vec::new();
|
||||
|
||||
for record in new_records.into_inner().into_iter() {
|
||||
let this_record = record.clone();
|
||||
if let Ok(record) = record.try_into() {
|
||||
records.push(record);
|
||||
} else {
|
||||
bad_records.push(this_record.clone());
|
||||
}
|
||||
}
|
||||
|
||||
if !bad_records.is_empty() {
|
||||
return models::ErrorResponse::new(
|
||||
Status::BadRequest,
|
||||
"Record list contains records that could not been parsed into DNS records".into()
|
||||
).with_details(
|
||||
json!({
|
||||
"zone_name": zone.to_utf8(),
|
||||
"records": bad_records
|
||||
})
|
||||
).err();
|
||||
}
|
||||
|
||||
let mut dns_api = dns::DnsApiClient::new(client);
|
||||
dns_api.add_records(zone.clone(), dns::DNSClass::IN, records).await?;
|
||||
|
||||
dns_api.add_records(
|
||||
zone.clone(),
|
||||
models::DNSClass::IN.into(),
|
||||
new_records.into_inner().try_into_dns_type(zone.into_inner())?
|
||||
).await?;
|
||||
|
||||
return Ok(Json(()));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue