diff options
Diffstat (limited to 'tools/emacs-pkgs/defzone/defzone.el')
-rw-r--r-- | tools/emacs-pkgs/defzone/defzone.el | 76 |
1 files changed, 44 insertions, 32 deletions
diff --git a/tools/emacs-pkgs/defzone/defzone.el b/tools/emacs-pkgs/defzone/defzone.el index b67501cbd860..ffd359e5ff83 100644 --- a/tools/emacs-pkgs/defzone/defzone.el +++ b/tools/emacs-pkgs/defzone/defzone.el @@ -8,38 +8,50 @@ "Evaluate a record definition and turn it into a zone file record in ZONE, optionally prefixed with SUBDOMAIN." - (declare (indent defun)) ; TODO(tazjin): remove - (let ((name (if subdomain (s-join "." (list subdomain zone)) zone))) - (pcase record - (`(SOA . (,ttl . (,mname ,rname ,serial ,refresh ,retry ,expire ,min))) - (format "%s %s IN SOA %s %s %s %s %s %s %s" - name ttl mname rname serial refresh retry expire min)) - - (`(NS . (,ttl . ,targets)) - (->> targets - (-map (lambda (target) (format "%s %s IN NS %s" name ttl target))) - (s-join "\n"))) - - (`(MX . (,ttl . ,pairs)) - (->> pairs - (-map (-lambda ((preference . exchange)) - (format "%s %s IN MX %s %s" name ttl preference exchange))) - (s-join "\n"))) - - (`(TXT ,ttl ,text) (format "%s %s IN TXT %s" name ttl (prin1-to-string text))) - - (`(A . (,ttl . ,ips)) - (->> ips - (-map (lambda (ip) (format "%s %s IN A %s" name ttl ip))) - (s-join "\n"))) - - (`(CNAME ,ttl ,target) (format "%s %s IN CNAME %s" name ttl target)) - - ((and `(,sub . ,records) - (guard (stringp sub))) - (s-join "\n" (-map (lambda (r) (record-to-record zone r sub)) records))) - - (_ (error "Invalid record definition: %s" record))))) + (cl-labels ((plist->alist (plist) + (when plist + (cons + (cons (car plist) (cadr plist)) + (plist->alist (cddr plist)))))) + (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)) + (->> targets + (-map (lambda (target) (format "%s %s IN NS %s" name ttl target))) + (s-join "\n"))) + + (`(MX . (,ttl . ,pairs)) + (->> pairs + (-map (-lambda ((preference . exchange)) + (format "%s %s IN MX %s %s" name ttl preference exchange))) + (s-join "\n"))) + + (`(TXT ,ttl ,text) (format "%s %s IN TXT %s" name ttl (prin1-to-string text))) + + (`(A . (,ttl . ,ips)) + (->> ips + (-map (lambda (ip) (format "%s %s IN A %s" name ttl ip))) + (s-join "\n"))) + + (`(CNAME ,ttl ,target) (format "%s %s IN CNAME %s" name ttl target)) + + ((and `(,sub . ,records) + (guard (stringp sub))) + (s-join "\n" (-map (lambda (r) (record-to-record zone r sub)) records))) + + (_ (error "Invalid record definition: %s" record)))))) (defmacro defzone (fqdn &rest records) "Generate zone file for the zone at FQDN from a simple DSL." |