112 lines
4.4 KiB
Text
112 lines
4.4 KiB
Text
|
|
use ./nulib/coredns/mod.nu *
|
||
|
|
|
||
|
|
export def get-provider-metadata []: nothing -> record {
|
||
|
|
{
|
||
|
|
name: "coredns"
|
||
|
|
version: "1.0.0"
|
||
|
|
type: "dns"
|
||
|
|
description: "CoreDNS VPN split-horizon provider — manages hosts entries in Corefile via SSH"
|
||
|
|
|
||
|
|
capabilities: {
|
||
|
|
server_management: false
|
||
|
|
network_management: false
|
||
|
|
storage_management: false
|
||
|
|
load_balancer: false
|
||
|
|
firewall: false
|
||
|
|
floating_ip: false
|
||
|
|
dns_management: true
|
||
|
|
}
|
||
|
|
|
||
|
|
api: {
|
||
|
|
type: "ssh"
|
||
|
|
base_url: ""
|
||
|
|
auth_method: "ssh_key"
|
||
|
|
documentation: ""
|
||
|
|
version: "1"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Normalize a raw hosts-block entry to the canonical DNS record format.
|
||
|
|
def to-dns-record [entry: record, zone: string]: nothing -> record {
|
||
|
|
{
|
||
|
|
id: $"($zone)/($entry.name)",
|
||
|
|
zone: $zone,
|
||
|
|
name: $entry.name,
|
||
|
|
type: "A",
|
||
|
|
value: $entry.value,
|
||
|
|
ttl: 300,
|
||
|
|
proxied: false,
|
||
|
|
source: "coredns",
|
||
|
|
priority: null,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# DNS interface — zone metadata (whether the zone block exists in the Corefile).
|
||
|
|
export def dns_zone_get [zone: string]: nothing -> record {
|
||
|
|
let cfg = (load-coredns-config)
|
||
|
|
let content = (fetch-corefile $cfg.ssh_host $cfg.corefile)
|
||
|
|
let has_zone = (corefile-has-zone $content $zone)
|
||
|
|
{
|
||
|
|
zone: $zone,
|
||
|
|
provider: "coredns",
|
||
|
|
exists: $has_zone,
|
||
|
|
ssh_host: $cfg.ssh_host,
|
||
|
|
service: $cfg.service,
|
||
|
|
corefile: $cfg.corefile,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# DNS interface — list all A records in the zone's hosts block.
|
||
|
|
export def dns_record_list [zone: string]: nothing -> list {
|
||
|
|
let cfg = (load-coredns-config)
|
||
|
|
let content = (fetch-corefile $cfg.ssh_host $cfg.corefile)
|
||
|
|
(corefile-parse-zone-hosts $content $zone)
|
||
|
|
| each {|e| to-dns-record $e $zone }
|
||
|
|
}
|
||
|
|
|
||
|
|
# DNS interface — add a record. Errors if zone block has no hosts section.
|
||
|
|
export def dns_record_create [rec: record]: nothing -> record {
|
||
|
|
dns_record_upsert $rec
|
||
|
|
}
|
||
|
|
|
||
|
|
# DNS interface — update a record by id. The id encodes zone/name.
|
||
|
|
export def dns_record_update [record_id: string, rec: record]: nothing -> record {
|
||
|
|
dns_record_upsert $rec
|
||
|
|
}
|
||
|
|
|
||
|
|
# DNS interface — remove a record by id. id format: "zone/name".
|
||
|
|
export def dns_record_delete [record_id: string, zone: string]: nothing -> nothing {
|
||
|
|
let name = ($record_id | split row "/" | last)
|
||
|
|
let cfg = (load-coredns-config)
|
||
|
|
let content = (fetch-corefile $cfg.ssh_host $cfg.corefile)
|
||
|
|
let current = (corefile-parse-zone-hosts $content $zone)
|
||
|
|
let updated = ($current | where { $in.name != $name })
|
||
|
|
if ($updated | length) == ($current | length) { return }
|
||
|
|
let new_content = (corefile-set-zone-hosts $content $zone $updated)
|
||
|
|
write-corefile $cfg.ssh_host $cfg.corefile $new_content
|
||
|
|
reload-coredns $cfg.ssh_host $cfg.service
|
||
|
|
}
|
||
|
|
|
||
|
|
# DNS interface — add or update a record in the zone's hosts block, then hot-reload.
|
||
|
|
export def dns_record_upsert [rec: record]: nothing -> record {
|
||
|
|
let cfg = (load-coredns-config)
|
||
|
|
let content = (fetch-corefile $cfg.ssh_host $cfg.corefile)
|
||
|
|
let current = (corefile-parse-zone-hosts $content $rec.zone)
|
||
|
|
let new_entry = { name: $rec.name, value: $rec.value }
|
||
|
|
let updated = ($current | where { $in.name != $rec.name } | append $new_entry)
|
||
|
|
let new_content = (corefile-set-zone-hosts $content $rec.zone $updated)
|
||
|
|
write-corefile $cfg.ssh_host $cfg.corefile $new_content
|
||
|
|
reload-coredns $cfg.ssh_host $cfg.service
|
||
|
|
to-dns-record $new_entry $rec.zone
|
||
|
|
}
|
||
|
|
|
||
|
|
# Stub compute functions — CoreDNS is DNS-only.
|
||
|
|
export def query_servers [find?: string, cols?: string]: nothing -> list { [] }
|
||
|
|
export def server_info [server: string, check: bool, find?: string, cols?: string]: nothing -> record { {} }
|
||
|
|
export def server_exists [server: string, error_exit: bool]: nothing -> bool { false }
|
||
|
|
export def server_is_running [server: string, error_exit: bool]: nothing -> bool { false }
|
||
|
|
export def check_server_requirements [settings: record, server: record, check: bool]: nothing -> bool { false }
|
||
|
|
export def delete_server [settings: record, server: record, keep_storage: bool, error_exit: bool]: nothing -> bool { false }
|
||
|
|
export def get_ip [settings: record, server: string, ip_type: string, error_exit: bool]: nothing -> string { "" }
|