diff options
author | Vincent Ambo <tazjin@google.com> | 2019-12-22T03·07+0000 |
---|---|---|
committer | Vincent Ambo <tazjin@google.com> | 2020-04-20T21·39+0100 |
commit | 5cc37a15a5a5d1b4950c79b2298806dbadde4643 (patch) | |
tree | 8e0faabe0ae3e71e0590988dbf087416276b60a9 /tools/emacs-pkgs/defzone/defzone.el | |
parent | 8c86b9b5f60af4d2bd16352ace7b19fdde04ffda (diff) |
feat(defzone): Add plist argument format for SOA records r/642
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.
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." |