add delete route
This commit is contained in:
parent
5f18e32615
commit
bc77bb16d4
6 changed files with 124 additions and 10 deletions
12
api.yml
12
api.yml
|
@ -423,3 +423,15 @@ paths:
|
|||
'200':
|
||||
description: ''
|
||||
|
||||
delete:
|
||||
security:
|
||||
- ApiToken: []
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RecordList'
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
|
||||
|
|
25
e2e/zones.py
25
e2e/zones.py
|
@ -117,7 +117,7 @@ class TestZones(unittest.TestCase):
|
|||
type='TXT'
|
||||
)
|
||||
|
||||
self.api.zones_zone_records_post(zone='example.com.', record_list=RecordList(value=[old_record]))
|
||||
self.api.zones_zone_records_post(zone='example.com.', record_list=RecordList([old_record]))
|
||||
|
||||
update_records_request = UpdateRecordsRequest(
|
||||
old_records=RecordList([old_record]),
|
||||
|
@ -133,4 +133,25 @@ class TestZones(unittest.TestCase):
|
|||
self.assertEqual(record.text, new_record.text, msg='New record does not have the expected value')
|
||||
found = True
|
||||
|
||||
self.assertTrue(found, msg='New record not found in zone records')
|
||||
self.assertTrue(found, msg='Updated record not found in zone records')
|
||||
|
||||
def test_delete_records(self):
|
||||
name = random_name('example.com.')
|
||||
record = RecordTypeTXT(
|
||||
_class='IN',
|
||||
ttl=300,
|
||||
name=name,
|
||||
text=random_string(32),
|
||||
type='TXT'
|
||||
)
|
||||
|
||||
self.api.zones_zone_records_post(zone='example.com.', record_list=RecordList([record]))
|
||||
self.api.zones_zone_records_delete(zone='example.com.', record_list=RecordList([record]))
|
||||
|
||||
records = self.api.zones_zone_records_get(zone='example.com.')
|
||||
found = False
|
||||
for record in records.value:
|
||||
if type(record) is RecordTypeTXT and record.name == name:
|
||||
found = True
|
||||
|
||||
self.assertFalse(found, msg='Delete record found in zone records')
|
|
@ -11,6 +11,7 @@ pub trait RecordApi {
|
|||
async fn get_records(&mut self, zone: dns::Name, class: dns::DNSClass) -> Result<Vec<dns::Record>, Self::Error>;
|
||||
async fn add_records(&mut self, zone: dns::Name, class: dns::DNSClass, new_records: Vec<dns::Record>) -> Result<(), Self::Error>;
|
||||
async fn update_records(&mut self, zone: dns::Name, class: dns::DNSClass, old_records: Vec<dns::Record>, new_records: Vec<dns::Record>) -> Result<(), Self::Error>;
|
||||
async fn delete_records(&mut self, zone: dns::Name, class: dns::DNSClass, records: Vec<dns::Record>) -> Result<(), Self::Error>;
|
||||
// delete_records
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@ use super::client::{ClientResponse, DnsClient};
|
|||
use super::api::{RecordApi, ZoneApi};
|
||||
|
||||
|
||||
const MAX_PAYLOAD_LEN: u16 = 1232;
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DnsApiError {
|
||||
ClientError(ClientError),
|
||||
|
@ -82,7 +85,7 @@ impl RecordApi for DnsApiClient {
|
|||
|
||||
{
|
||||
let edns = message.edns_mut();
|
||||
edns.set_max_payload(1232);
|
||||
edns.set_max_payload(MAX_PAYLOAD_LEN);
|
||||
edns.set_version(0);
|
||||
}
|
||||
|
||||
|
@ -100,12 +103,11 @@ impl RecordApi for DnsApiClient {
|
|||
|
||||
async fn update_records(&mut self, zone: Name, class: DNSClass, old_records: Vec<Record>, new_records: Vec<Record>) -> Result<(), Self::Error>
|
||||
{
|
||||
|
||||
// Taken from trust_dns_client::op::update_message::compare_and_swap
|
||||
// The original function can not be used as is because it takes a RecordSet and not a Record list
|
||||
|
||||
// for updates, the query section is used for the zone
|
||||
let mut zone_query: Query = Query::new();
|
||||
let mut zone_query = Query::new();
|
||||
zone_query.set_name(zone.clone())
|
||||
.set_query_class(class)
|
||||
.set_query_type(RecordType::SOA);
|
||||
|
@ -130,8 +132,8 @@ impl RecordApi for DnsApiClient {
|
|||
|
||||
// add the delete for the old record
|
||||
let mut delete = old_records;
|
||||
// the class must be none for delete
|
||||
for record in delete.iter_mut() {
|
||||
// the class must be none for delete
|
||||
record.set_dns_class(DNSClass::NONE);
|
||||
// the TTL should be 0
|
||||
record.set_ttl(0);
|
||||
|
@ -144,7 +146,7 @@ impl RecordApi for DnsApiClient {
|
|||
// Extended dns
|
||||
{
|
||||
let edns = message.edns_mut();
|
||||
edns.set_max_payload(1232);
|
||||
edns.set_max_payload(MAX_PAYLOAD_LEN);
|
||||
edns.set_version(0);
|
||||
}
|
||||
|
||||
|
@ -159,6 +161,55 @@ impl RecordApi for DnsApiClient {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn delete_records(&mut self, zone: Name, class: DNSClass, records: Vec<Record>) -> Result<(), Self::Error>
|
||||
{
|
||||
// for updates, the query section is used for the zone
|
||||
let mut zone_query = Query::new();
|
||||
zone_query.set_name(zone.clone())
|
||||
.set_query_class(class)
|
||||
.set_query_type(RecordType::SOA);
|
||||
|
||||
let mut message: Message = Message::new();
|
||||
|
||||
// build the message
|
||||
// TODO: set random / time based id
|
||||
message
|
||||
.set_id(0)
|
||||
.set_message_type(MessageType::Query)
|
||||
.set_op_code(OpCode::Update)
|
||||
.set_recursion_desired(false);
|
||||
message.add_zone(zone_query);
|
||||
|
||||
let mut delete = records;
|
||||
|
||||
for record in delete.iter_mut() {
|
||||
// the class must be none for delete
|
||||
record.set_dns_class(DNSClass::NONE);
|
||||
// the TTL should be 0
|
||||
record.set_ttl(0);
|
||||
}
|
||||
message.add_updates(delete);
|
||||
|
||||
// Extended dns
|
||||
{
|
||||
let edns = message.edns_mut();
|
||||
edns.set_max_payload(MAX_PAYLOAD_LEN);
|
||||
edns.set_version(0);
|
||||
}
|
||||
|
||||
let response = ClientResponse(self.client.send(message)).await.map_err(|e| DnsApiError::ClientError(e))?;
|
||||
|
||||
if response.response_code() != ResponseCode::NoError {
|
||||
return Err(DnsApiError::ResponceNotOk {
|
||||
code: response.response_code(),
|
||||
zone: zone,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,10 +29,11 @@ async fn rocket() -> rocket::Rocket {
|
|||
get_zone_records,
|
||||
create_zone_records,
|
||||
update_zone_records,
|
||||
delete_zone_records,
|
||||
get_zones,
|
||||
create_zone,
|
||||
add_member_to_zone,
|
||||
create_auth_token,
|
||||
create_user
|
||||
create_user,
|
||||
])
|
||||
}
|
||||
|
|
|
@ -56,7 +56,6 @@ pub async fn create_zone_records(
|
|||
}
|
||||
}).await?;
|
||||
|
||||
|
||||
let mut dns_api = DnsApiClient::new(client);
|
||||
|
||||
dns_api.add_records(
|
||||
|
@ -90,7 +89,6 @@ pub async fn update_zone_records(
|
|||
}
|
||||
}).await?;
|
||||
|
||||
|
||||
let mut dns_api = DnsApiClient::new(client);
|
||||
|
||||
dns_api.update_records(
|
||||
|
@ -103,6 +101,36 @@ pub async fn update_zone_records(
|
|||
return Ok(Json(()));
|
||||
}
|
||||
|
||||
#[delete("/zones/<zone>/records", data = "<records>")]
|
||||
pub async fn delete_zone_records(
|
||||
client: DnsClient,
|
||||
conn: DbConn,
|
||||
user_info: Result<models::UserInfo, models::ErrorResponse>,
|
||||
zone: models::AbsoluteName,
|
||||
records: Json<models::RecordList>
|
||||
) -> Result<Json<()>, models::ErrorResponse> {
|
||||
|
||||
let user_info = user_info?;
|
||||
let zone_name = zone.to_utf8();
|
||||
|
||||
conn.run(move |c| {
|
||||
if user_info.is_admin() {
|
||||
models::Zone::get_by_name(c, &zone_name)
|
||||
} else {
|
||||
user_info.get_zone(c, &zone_name)
|
||||
}
|
||||
}).await?;
|
||||
|
||||
let mut dns_api = DnsApiClient::new(client);
|
||||
|
||||
dns_api.delete_records(
|
||||
zone.clone(),
|
||||
models::DNSClass::IN.into(),
|
||||
records.into_inner().try_into_dns_type(zone.into_inner(), models::DNSClass::IN.into())?
|
||||
).await?;
|
||||
|
||||
return Ok(Json(()));
|
||||
}
|
||||
|
||||
#[get("/zones")]
|
||||
pub async fn get_zones(
|
||||
|
|
Loading…
Reference in a new issue