Babashka script
This commit is contained in:
parent
e62077ef9a
commit
2b8e714210
|
@ -0,0 +1,170 @@
|
||||||
|
#!/usr/bin bb
|
||||||
|
(ns
|
||||||
|
(:require [babashka.curl :as curl])
|
||||||
|
(:import (java.nio.file Files
|
||||||
|
LinkOption)
|
||||||
|
(java.nio.file.attribute PosixFileAttributeView
|
||||||
|
FileAttribute)
|
||||||
|
(java.io BufferedReader File)
|
||||||
|
(java.util.regex Pattern)))
|
||||||
|
|
||||||
|
(defn sh
|
||||||
|
"Launches a process with optional args, returning the exit code.
|
||||||
|
Prints stdout & stderr."
|
||||||
|
[bin & args]
|
||||||
|
(let [arg-array ^"[Ljava.lang.String;]" (into-array String (cons bin args))
|
||||||
|
process (-> (ProcessBuilder. arg-array)
|
||||||
|
(.redirectErrorStream true) ;; TODO stream stderr to stderr
|
||||||
|
(.start))]
|
||||||
|
(with-open [out (io/reader (.getInputStream process))]
|
||||||
|
(loop []
|
||||||
|
(when-let [line (.readLine ^BufferedReader out)]
|
||||||
|
(println line)
|
||||||
|
(recur))))
|
||||||
|
(.waitFor process)))
|
||||||
|
|
||||||
|
;; ## Deployment directory structure
|
||||||
|
(defn set-owner [path owner]
|
||||||
|
(->
|
||||||
|
(Files/getFileAttributeView path PosixFileAttributeView (into-array LinkOption [LinkOption/NOFOLLOW_LINKS]))
|
||||||
|
(.setOwner owner)))
|
||||||
|
|
||||||
|
(defn set-group [path group]
|
||||||
|
(->
|
||||||
|
(Files/getFileAttributeView path PosixFileAttributeView (into-array LinkOption [LinkOption/NOFOLLOW_LINKS]))
|
||||||
|
(.setGroup group)))
|
||||||
|
|
||||||
|
(defn make-dirs! [{:keys [company-name]}]
|
||||||
|
(printf "Creating deploy directories for %s." company-name)
|
||||||
|
(let [attrs (Files/getFileAttributeView (.toPath (io/file "/srv/http/www.sompani.com"))
|
||||||
|
PosixFileAttributeView
|
||||||
|
(into-array LinkOption [LinkOption/NOFOLLOW_LINKS]))
|
||||||
|
owner (.getOwner attrs)
|
||||||
|
fattr (into-array FileAttribute [])]
|
||||||
|
(doseq [dir-str ["/srv/http/staging.%s.talent.careers-cache"
|
||||||
|
"/srv/http/staging.%s.talent.careers-logs"
|
||||||
|
"/srv/http/staging.%s.talent.careers-sessions"
|
||||||
|
"/srv/http/staging.%s.talent.careers-uploads"
|
||||||
|
"/srv/http/staging.%s.talent.careers.1234"
|
||||||
|
"/srv/http/%s.talent.careers-cache"
|
||||||
|
"/srv/http/%s.talent.careers-logs"
|
||||||
|
"/srv/http/%s.talent.careers-sessions"
|
||||||
|
"/srv/http/%s.talent.careers-uploads"
|
||||||
|
"/srv/http/%s.talent.careers.1234"]
|
||||||
|
:let [dir (.toPath (io/file (format dir-str company-name)))]]
|
||||||
|
(printf ".")
|
||||||
|
(and
|
||||||
|
(Files/createDirectory dir fattr)
|
||||||
|
(set-owner dir owner)))
|
||||||
|
(printf ".")
|
||||||
|
(let [link (.toPath (io/file (format "/srv/http/staging.%s.talent.careers" company-name)))]
|
||||||
|
(and
|
||||||
|
(Files/createSymbolicLink link
|
||||||
|
(.toPath (io/file (format "/srv/http/staging.%s.talent.careers.1234" company-name)))
|
||||||
|
fattr)
|
||||||
|
(set-owner link owner)))
|
||||||
|
|
||||||
|
(printf ".")
|
||||||
|
(let [link (.toPath (io/file (format "/srv/http/%s.talent.careers" company-name)))]
|
||||||
|
(and
|
||||||
|
(Files/createSymbolicLink link
|
||||||
|
(.toPath (io/file (format "/srv/http/%s.talent.careers.1234" company-name)))
|
||||||
|
fattr)
|
||||||
|
(set-owner link owner)))
|
||||||
|
(printf " ok.\n")))
|
||||||
|
|
||||||
|
;; ## nginx configuration
|
||||||
|
(defn render-replace [input datamap]
|
||||||
|
(reduce
|
||||||
|
#(str/replace %1 (Pattern/compile (str "\{\{" (name (key %2)) "\}\}")) (val %2))
|
||||||
|
input
|
||||||
|
datamap))
|
||||||
|
|
||||||
|
(defn create-nginx-server! [{:keys [company-name] :as datamap}]
|
||||||
|
(printf "Creating nginx entries for %n." company-name)
|
||||||
|
(doseq [file ["skel.talent.careers"
|
||||||
|
"staging.skel.talent.careers"]
|
||||||
|
:let [in-file (str "resources/nginx/" file)
|
||||||
|
out-file (format "/etc/nginx/servers-available/%s" (str/replace file #"skel" company-name))]]
|
||||||
|
(printf ".")
|
||||||
|
(spit out-file
|
||||||
|
(render-replace (slurp in-file) datamap)))
|
||||||
|
(printf " ok.\n"))
|
||||||
|
|
||||||
|
;; ## Certificates
|
||||||
|
(defn generate-certs! [{:keys [company-name company-domain] :as datamap}]
|
||||||
|
(println "Generating certificates...")
|
||||||
|
(let [command (map #(render-replace % datamap)
|
||||||
|
["certbot" "certonly" "--nginx"
|
||||||
|
"-d" "staging.{{company-name}}.talent.careers"
|
||||||
|
"-d" "{{company-name}}.talent.careers"
|
||||||
|
"-d" "talent.{{company-domain}}"
|
||||||
|
"-d" "www.talent.{{company-domain}}"
|
||||||
|
"--cert-name" "{{company-name}}"])]
|
||||||
|
(println "Executing " (pr-str command))
|
||||||
|
(apply sh command))
|
||||||
|
(println "ok."))
|
||||||
|
|
||||||
|
;; # DNS Configuration
|
||||||
|
|
||||||
|
;; ## Basic cloudflare entries
|
||||||
|
|
||||||
|
(defn basic-dns-entries [company-name]
|
||||||
|
[{:type "A" :name company-name :content "185.163.117.139"}
|
||||||
|
{:type "A" :name (format "staging.%s" company-name) :content "185.163.117.139"}
|
||||||
|
{:type "AAAA" :name company-name :content "2a03:4000:3b:2bb:18ea:e0ff:fe8c:aa9a"}
|
||||||
|
{:type "AAAA" :name (format "staging.%s" company-name) :content "2a03:4000:3b:2bb:18ea:e0ff:fe8c:aa9a"}
|
||||||
|
{:type "MX" :name company-name :content "mx.yandex.net."}
|
||||||
|
{:type "MX" :name (format "m.%s.talent.careers" company-name) :content "feedback-smtp.eu-west-1.amazonses.com"}
|
||||||
|
{:type "TXT" :name (format "m.%s.talent.careers" company-name) :content "v=spf1 include:amazonses.com ~all"}
|
||||||
|
{:type "TXT" :name (format "%s.talent.careers" company-name) :content "v=spf1 redirect=_spf.yandex.net"}
|
||||||
|
{:type "TXT" :name (format "_dmarc.%s" company-name) :content "v=DMARC1; p=none; rua=sompani-d@dmarc.report-uri.com"}])
|
||||||
|
|
||||||
|
(defn make-dns-entries! [entries]
|
||||||
|
(let [uri "https://api.cloudflare.com/client/v4/zones/5cd643e7432d7cf69f44e268e32b5452/dns_records"
|
||||||
|
headers {"Authorization" (str "Bearer " (System/getenv "CLOUDFLARE_API"))}]
|
||||||
|
(doseq [entry entries]
|
||||||
|
(printf ".")
|
||||||
|
(curl/post uri
|
||||||
|
{:headers headers
|
||||||
|
:content-type :json
|
||||||
|
:form-params entry}))))
|
||||||
|
|
||||||
|
(defn make-basic-dns-entries [{:keys [company-name]}]
|
||||||
|
(printf "Creating basic DNS entries for %s." company-name)
|
||||||
|
(make-dns-entries! (basic-dns-entries company-name))
|
||||||
|
(println " ok."))
|
||||||
|
|
||||||
|
;; # Main initialization
|
||||||
|
(def cli-options
|
||||||
|
[["-d" "--domain VCDOMAIN" "The domain of the VC to onboard"
|
||||||
|
:default nil
|
||||||
|
:id :vc-domain]
|
||||||
|
["-n" "--name VCNAME" "The name of the VC to onboard"
|
||||||
|
:default nil
|
||||||
|
:id :vc-name]
|
||||||
|
[nil "--deploy-directories" "Create deploy directories"]
|
||||||
|
[nil "--base-dns" "Create basic DNS entries. Make sure to have the CLOUDFLARE_API env var set."]
|
||||||
|
[nil "--nginx" "Create nginx entries"]
|
||||||
|
[nil "--certify" "Generate certificates"]
|
||||||
|
["-h" "--help"]])
|
||||||
|
|
||||||
|
(let [{:keys [vc-domain
|
||||||
|
vc-name
|
||||||
|
deploy-directories
|
||||||
|
base-dns
|
||||||
|
aws-domain
|
||||||
|
nginx
|
||||||
|
certify
|
||||||
|
help]
|
||||||
|
:as options}
|
||||||
|
(:options (tools.cli/parse-opts args cli-options))
|
||||||
|
datamap {:company-name vc-name :company-domain vc-domain}]
|
||||||
|
(if help
|
||||||
|
(println (:summary (tools.cli/parse-opts args cli-options)))
|
||||||
|
(do
|
||||||
|
(and deploy-directories (make-dirs! datamap))
|
||||||
|
(and base-dns (make-basic-dns-entries! datamap))
|
||||||
|
(and nginx (create-nginx-server! datamap))
|
||||||
|
(and certify (generate-certs! datamap))
|
||||||
|
(println "Done."))))
|
Loading…
Reference in New Issue