watch-ssh-keys.fnl (2062B)
1 (local { : system : assoc : split : dup : table= : dig : append-path } (require :anoia)) 2 (local svc (require :anoia.svc)) 3 (import-macros { : define-tests : expect : expect= } :anoia.assert) 4 5 (fn parse-args [args] 6 (match args 7 ["-d" path & rest] (assoc (parse-args rest) 8 :out-path path) 9 [watched-service path] { : watched-service 10 : path })) 11 12 (fn write-changes [path old-tree new-tree] 13 (when (not (table= old-tree new-tree)) 14 (io.stderr:write "new ssh keys\n") 15 (each [username pubkeys (pairs new-tree)] 16 (with-open [f (assert (io.open (append-path path username) :w))] 17 ;; the keys are "1" "2" "3" etc, so pairs not ipairs 18 (each [_ k (pairs pubkeys)] 19 (f:write k) 20 (f:write "\n"))))) 21 (each [k v (pairs old-tree)] 22 (when (not (. new-tree k)) 23 (os.remove (append-path path k)))) 24 new-tree) 25 26 (define-tests 27 (local { : file-exists? } (require :anoia)) 28 (print "running tests") 29 (let [tree { 30 "dan" ["f1" "f2"] 31 "root" ["f1"] 32 } 33 out-dir (: (assert (io.popen "mktemp -d -p '' fennel-XXXXXXX" :r)) :read "l")] 34 ;; if the trees are identical, nothing is written 35 (write-changes out-dir tree tree) 36 (expect (not (file-exists? (.. out-dir "/dan")))) 37 38 ;; add an entry 39 (write-changes out-dir tree (assoc (dup tree) "geoffrey" ["rr"])) 40 (expect (file-exists? (.. out-dir "/dan"))) 41 (expect= (with-open [f (io.open (.. out-dir "/geoffrey"))] (f:read "*a")) "rr\n") 42 43 ;; newly-missing entries are removed 44 (write-changes out-dir (assoc (dup tree) "geoffrey" ["rr"]) tree) 45 (expect (not (file-exists? (.. out-dir "/geoffrey")))) 46 47 (write-changes out-dir tree {}) 48 (os.remove out-dir) 49 )) 50 51 (fn run [] 52 (let [{: out-path : watched-service : path } (parse-args arg) 53 service (assert (svc.open watched-service))] 54 (accumulate [tree {} 55 v (service:events)] 56 (write-changes out-path tree (or (service:output path) {}))))) 57 58 59 { : run }