diff options
author | Vincent Ambo <tazjin@google.com> | 2019-12-22T01·16+0000 |
---|---|---|
committer | Vincent Ambo <tazjin@google.com> | 2020-04-20T21·39+0100 |
commit | 8c86b9b5f60af4d2bd16352ace7b19fdde04ffda (patch) | |
tree | 8ab32c4c09e7e2ce64562936bb323962e9b537c6 /tools/emacs-pkgs/defzone/defzone.el | |
parent | d6f5ca7cafcaad006697abedfb40c885427f3d58 (diff) |
feat(defzone): Add an Emacs package for generating zone files r/641
This currently only supports a small subset of available records, but I actually kind of like the nesting.
Diffstat (limited to 'tools/emacs-pkgs/defzone/defzone.el')
-rw-r--r-- | tools/emacs-pkgs/defzone/defzone.el | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/tools/emacs-pkgs/defzone/defzone.el b/tools/emacs-pkgs/defzone/defzone.el new file mode 100644 index 000000000000..b67501cbd860 --- /dev/null +++ b/tools/emacs-pkgs/defzone/defzone.el @@ -0,0 +1,48 @@ +;;; defzone.el --- Generate zone files from Elisp -*- lexical-binding: t; -*- + +(require 'dash) +(require 'dash-functional) +(require 's) + +(defun record-to-record (zone record &optional subdomain) + "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))))) + +(defmacro defzone (fqdn &rest records) + "Generate zone file for the zone at FQDN from a simple DSL." + (declare (indent defun)) + + `(s-join "\n" (-map (lambda (r) (record-to-record ,fqdn r)) (quote ,records)))) |