feat(defzone): Add plist argument format for SOA records
These records have so many fields that it's difficult to track what's what in a long list. For convenience they're now specified in plist format (see the example). There isn't really a point to this because the SOA record is the one I care the *least* about practically as Cloud DNS sets it for me, but whatever.
This commit is contained in:
parent
8c86b9b5f6
commit
5cc37a15a5
2 changed files with 45 additions and 27 deletions
|
@ -8,38 +8,50 @@
|
||||||
"Evaluate a record definition and turn it into a zone file
|
"Evaluate a record definition and turn it into a zone file
|
||||||
record in ZONE, optionally prefixed with SUBDOMAIN."
|
record in ZONE, optionally prefixed with SUBDOMAIN."
|
||||||
|
|
||||||
(declare (indent defun)) ; TODO(tazjin): remove
|
(cl-labels ((plist->alist (plist)
|
||||||
(let ((name (if subdomain (s-join "." (list subdomain zone)) zone)))
|
(when plist
|
||||||
(pcase record
|
(cons
|
||||||
(`(SOA . (,ttl . (,mname ,rname ,serial ,refresh ,retry ,expire ,min)))
|
(cons (car plist) (cadr plist))
|
||||||
(format "%s %s IN SOA %s %s %s %s %s %s %s"
|
(plist->alist (cddr plist))))))
|
||||||
name ttl mname rname serial refresh retry expire min))
|
(let ((name (if subdomain (s-join "." (list subdomain zone)) zone)))
|
||||||
|
(pcase record
|
||||||
|
;; SOA RDATA (RFC 1035; 3.3.13)
|
||||||
|
((and `(SOA . (,ttl . ,keys))
|
||||||
|
(let (map (:mname mname) (:rname rname) (:serial serial)
|
||||||
|
(:refresh refresh) (:retry retry) (:expire expire)
|
||||||
|
(:minimum min))
|
||||||
|
(plist->alist keys)))
|
||||||
|
(if-let ((missing (-filter #'null (not (list mname rname serial
|
||||||
|
refresh retry expire min)))))
|
||||||
|
(error "Missing fields in SOA record: %s" missing)
|
||||||
|
(format "%s %s IN SOA %s %s %s %s %s %s %s"
|
||||||
|
name ttl mname rname serial refresh retry expire min)))
|
||||||
|
|
||||||
(`(NS . (,ttl . ,targets))
|
(`(NS . (,ttl . ,targets))
|
||||||
(->> targets
|
(->> targets
|
||||||
(-map (lambda (target) (format "%s %s IN NS %s" name ttl target)))
|
(-map (lambda (target) (format "%s %s IN NS %s" name ttl target)))
|
||||||
(s-join "\n")))
|
(s-join "\n")))
|
||||||
|
|
||||||
(`(MX . (,ttl . ,pairs))
|
(`(MX . (,ttl . ,pairs))
|
||||||
(->> pairs
|
(->> pairs
|
||||||
(-map (-lambda ((preference . exchange))
|
(-map (-lambda ((preference . exchange))
|
||||||
(format "%s %s IN MX %s %s" name ttl preference exchange)))
|
(format "%s %s IN MX %s %s" name ttl preference exchange)))
|
||||||
(s-join "\n")))
|
(s-join "\n")))
|
||||||
|
|
||||||
(`(TXT ,ttl ,text) (format "%s %s IN TXT %s" name ttl (prin1-to-string text)))
|
(`(TXT ,ttl ,text) (format "%s %s IN TXT %s" name ttl (prin1-to-string text)))
|
||||||
|
|
||||||
(`(A . (,ttl . ,ips))
|
(`(A . (,ttl . ,ips))
|
||||||
(->> ips
|
(->> ips
|
||||||
(-map (lambda (ip) (format "%s %s IN A %s" name ttl ip)))
|
(-map (lambda (ip) (format "%s %s IN A %s" name ttl ip)))
|
||||||
(s-join "\n")))
|
(s-join "\n")))
|
||||||
|
|
||||||
(`(CNAME ,ttl ,target) (format "%s %s IN CNAME %s" name ttl target))
|
(`(CNAME ,ttl ,target) (format "%s %s IN CNAME %s" name ttl target))
|
||||||
|
|
||||||
((and `(,sub . ,records)
|
((and `(,sub . ,records)
|
||||||
(guard (stringp sub)))
|
(guard (stringp sub)))
|
||||||
(s-join "\n" (-map (lambda (r) (record-to-record zone r sub)) records)))
|
(s-join "\n" (-map (lambda (r) (record-to-record zone r sub)) records)))
|
||||||
|
|
||||||
(_ (error "Invalid record definition: %s" record)))))
|
(_ (error "Invalid record definition: %s" record))))))
|
||||||
|
|
||||||
(defmacro defzone (fqdn &rest records)
|
(defmacro defzone (fqdn &rest records)
|
||||||
"Generate zone file for the zone at FQDN from a simple DSL."
|
"Generate zone file for the zone at FQDN from a simple DSL."
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
;;; example.el - usage example for defzone macro
|
;;; example.el - usage example for defzone macro
|
||||||
|
|
||||||
(defzone "tazj.in."
|
(defzone "tazj.in."
|
||||||
(SOA 21600 "ns-cloud-a1.googledomains.com." "cloud-dns-hostmaster.google.com."
|
(SOA 21600
|
||||||
123 21600 3600 1209600 300)
|
:mname "ns-cloud-a1.googledomains.com."
|
||||||
|
:rname "cloud-dns-hostmaster.google.com."
|
||||||
|
:serial 123
|
||||||
|
:refresh 21600
|
||||||
|
:retry 3600
|
||||||
|
:expire 1209600
|
||||||
|
:minimum 300)
|
||||||
|
|
||||||
(NS 21600
|
(NS 21600
|
||||||
"ns-cloud-a1.googledomains.com."
|
"ns-cloud-a1.googledomains.com."
|
||||||
|
|
Loading…
Reference in a new issue