basic zone configuration
This commit is contained in:
parent
76f222e1c4
commit
1f3aa12401
6 changed files with 111 additions and 10 deletions
24
dev-scripts/config/knot.conf
Normal file
24
dev-scripts/config/knot.conf
Normal file
|
@ -0,0 +1,24 @@
|
|||
server:
|
||||
listen: [ 0.0.0.0@5353, ::@5353 ]
|
||||
|
||||
log:
|
||||
- target: stderr
|
||||
any: debug
|
||||
|
||||
acl:
|
||||
- id: example_acl
|
||||
address: [ 127.0.0.1, ::1]
|
||||
action: transfer
|
||||
|
||||
template:
|
||||
- id: default
|
||||
file: "zones/%s.zone"
|
||||
journal-content: all
|
||||
zonefile-load: difference-no-serial
|
||||
zonefile-sync: -1
|
||||
serial-policy: dateserial
|
||||
|
||||
zone:
|
||||
- domain: example.com
|
||||
acl: example_acl
|
||||
template: default
|
8
dev-scripts/docker-compose.yml
Normal file
8
dev-scripts/docker-compose.yml
Normal file
|
@ -0,0 +1,8 @@
|
|||
services:
|
||||
knot:
|
||||
image: cznic/knot
|
||||
volumes:
|
||||
- $PWD/zones:/storage/zones:ro
|
||||
- $PWD/config:/config:ro
|
||||
command: knotd
|
||||
network_mode: host
|
13
dev-scripts/zones/example.com.zone
Normal file
13
dev-scripts/zones/example.com.zone
Normal file
|
@ -0,0 +1,13 @@
|
|||
example.com. IN SOA ns.example.com. admin.example.com. (
|
||||
2020250101 ; serial
|
||||
28800 ; refresh (8 hours)
|
||||
7200 ; retry (2 hours)
|
||||
2419200 ; expire (4 weeks)
|
||||
300 ; minimum (5 minutes)
|
||||
)
|
||||
|
||||
example.com. 84600 IN NS ns.example.com.
|
||||
|
||||
srv1.example.com. 600 IN A 198.51.100.3
|
||||
srv1.example.com. 600 IN AAAA 2001:db8:cafe:bc68::2
|
||||
www 600 IN CNAME srv1
|
|
@ -27,6 +27,7 @@ async fn rocket() -> rocket::Rocket {
|
|||
.mount("/api/v1", routes![
|
||||
get_zone_records,
|
||||
get_zones,
|
||||
create_zone,
|
||||
add_member_to_zone,
|
||||
create_auth_token,
|
||||
create_user
|
||||
|
|
|
@ -21,7 +21,7 @@ use crate::schema::*;
|
|||
use crate::DbConn;
|
||||
use crate::config::Config;
|
||||
use crate::models::errors::{ErrorResponse, make_500};
|
||||
|
||||
use crate::models::dns::AbsoluteName;
|
||||
|
||||
const BEARER: &str = "Bearer ";
|
||||
const AUTH_HEADER: &str = "Authentication";
|
||||
|
@ -82,6 +82,11 @@ pub struct AddZoneMemberRequest {
|
|||
pub id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct CreateZoneRequest {
|
||||
pub name: AbsoluteName,
|
||||
}
|
||||
|
||||
// pub struct LdapUserAssociation {
|
||||
// user_id: Uuid,
|
||||
// ldap_id: String
|
||||
|
@ -366,6 +371,25 @@ impl Zone {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn create_zone(conn: &diesel::SqliteConnection, zone_request: CreateZoneRequest) -> Result<Zone, UserError> {
|
||||
use crate::schema::zone::dsl::*;
|
||||
|
||||
let new_zone = Zone {
|
||||
id: Uuid::new_v4().to_simple().to_string(),
|
||||
name: zone_request.name.to_utf8(),
|
||||
};
|
||||
|
||||
diesel::insert_into(zone)
|
||||
.values(&new_zone)
|
||||
.execute(conn)
|
||||
.map_err(|e| match e {
|
||||
DieselError::DatabaseError(diesel::result::DatabaseErrorKind::UniqueViolation, _) => UserError::UserConflict,
|
||||
other => UserError::DbError(other)
|
||||
})?;
|
||||
Ok(new_zone)
|
||||
}
|
||||
|
||||
|
||||
pub fn add_member(&self, conn: &diesel::SqliteConnection, new_member: &UserInfo) -> Result<(), UserError> {
|
||||
use crate::schema::user_zone::dsl::*;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ use trust_dns_client::rr::{DNSClass, RecordType};
|
|||
|
||||
use crate::{DbConn, models::dns};
|
||||
use crate::models::errors::{ErrorResponse, make_500};
|
||||
use crate::models::users::{LocalUser, UserInfo, Zone, AddZoneMemberRequest};
|
||||
use crate::models::users::{LocalUser, UserInfo, Zone, AddZoneMemberRequest, CreateZoneRequest};
|
||||
|
||||
|
||||
#[get("/zones/<zone>/records")]
|
||||
|
@ -21,22 +21,23 @@ pub async fn get_zone_records(
|
|||
) -> Result<Json<Vec<dns::Record>>, ErrorResponse> {
|
||||
|
||||
let user_info = user_info?;
|
||||
let zone_name = zone.to_string();
|
||||
|
||||
if !user_info.is_admin() {
|
||||
let zone_name = zone.clone().to_string();
|
||||
conn.run(move |c| {
|
||||
if user_info.is_admin() {
|
||||
Zone::get_by_name(c, &zone_name)
|
||||
} else {
|
||||
user_info.get_zone(c, &zone_name)
|
||||
}).await?;
|
||||
}
|
||||
}).await?;
|
||||
|
||||
let response = {
|
||||
let query = client.query(zone.clone(), DNSClass::IN, RecordType::AXFR);
|
||||
query.await.map_err(make_500)?
|
||||
};
|
||||
|
||||
// TODO: Better error handling (ex. not authorized should be 500)
|
||||
if response.response_code() != ResponseCode::NoError {
|
||||
println!("Querrying of zone {} failed with code {}", *zone, response.response_code());
|
||||
println!("Querrying AXFR of zone {} failed with code {}", *zone, response.response_code());
|
||||
return ErrorResponse::new(
|
||||
Status::NotFound,
|
||||
format!("Zone {} could not be found", *zone)
|
||||
|
@ -55,7 +56,6 @@ pub async fn get_zone_records(
|
|||
Ok(Json(records))
|
||||
}
|
||||
|
||||
// TODO: the post version of that
|
||||
#[get("/zones")]
|
||||
pub async fn get_zones(
|
||||
conn: DbConn,
|
||||
|
@ -74,6 +74,37 @@ pub async fn get_zones(
|
|||
Ok(Json(zones))
|
||||
}
|
||||
|
||||
#[post("/zones", data = "<zone_request>")]
|
||||
pub async fn create_zone(
|
||||
conn: DbConn,
|
||||
mut client: dns::DnsClient,
|
||||
user_info: Result<UserInfo, ErrorResponse>,
|
||||
zone_request: Json<CreateZoneRequest>,
|
||||
) -> Result<Json<Zone>, ErrorResponse> {
|
||||
user_info?.check_admin()?;
|
||||
|
||||
|
||||
// Check if the zone exists in the DNS server
|
||||
let response = {
|
||||
let query = client.query(zone_request.name.clone(), DNSClass::IN, RecordType::SOA);
|
||||
query.await.map_err(make_500)?
|
||||
};
|
||||
|
||||
if response.response_code() != ResponseCode::NoError {
|
||||
println!("Querrying SOA of zone {} failed with code {}", *zone_request.name, response.response_code());
|
||||
return ErrorResponse::new(
|
||||
Status::NotFound,
|
||||
format!("Zone {} could not be found", *zone_request.name)
|
||||
).err()
|
||||
}
|
||||
|
||||
let zone = conn.run(move |c| {
|
||||
Zone::create_zone(c, zone_request.into_inner())
|
||||
}).await?;
|
||||
|
||||
Ok(Json(zone))
|
||||
}
|
||||
|
||||
|
||||
#[post("/zones/<zone>/members", data = "<zone_member_request>")]
|
||||
pub async fn add_member_to_zone<'r>(
|
||||
|
|
Loading…
Reference in a new issue