sompani-toolbox/src/com/sompani/onboarding.clj

134 lines
5.8 KiB
Clojure

(ns com.sompani.onboarding
(:require [clojure.java.shell :as sh]
[clojure.java.io :as io]
[clojure.string :as str]
[vault.core :as vault]
vault.client.http
[clj-http.client :as http]
[cljstache.core :as cljstache]
[taoensso.timbre :as timbre
:refer [log trace debug info warn error fatal report
logf tracef debugf infof warnf errorf fatalf reportf
spy get-env]])
(:import (java.nio.file Files
LinkOption)
(java.nio.file.attribute PosixFileAttributeView
FileAttribute)))
(def vault-client (vault/new-client "http://127.0.0.1:8200"))
;; # Webserver configuration
;; ## 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]}]
(let [attrs (Files/getFileAttributeView (.toPath (io/file "/srv/http/www.sompani.com"))
PosixFileAttributeView
(into-array LinkOption [LinkOption/NOFOLLOW_LINKS]))
;; group (.group attrs)
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)))]]
(Files/createDirectory dir fattr)
(set-owner dir owner)
;; (set-group dir group)
)
(let [link (.toPath (io/file (format "/srv/http/staging.%s.talent.careers" company-name)))]
(Files/createSymbolicLink link
(.toPath (io/file (format "/srv/http/staging.%s.talent.careers-1234" company-name)))
fattr)
(set-owner link owner)
;; (set-group link group)
)
(let [link (.toPath (io/file (format "/srv/http/%s.talent.careers" company-name)))]
(Files/createSymbolicLink link
(.toPath (io/file (format "/srv/http/%s.talent.careers-1234" company-name)))
fattr)
(set-owner link owner)
;; (set-group link group)
)))
;; ## nginx configuration
(defn create-nginx-server! [datamap]
(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 datamap)))]]
(info "using template" in-file "to create" out-file)
(spit out-file
(cljstache/render (slurp in-file) datamap))))
;; ## Certificates
(defn generate-certs! [{:keys [company-name company-suffix] :as datamap}]
(info
(apply sh/sh (map #(cljstache/render % datamap)
["certbot" "certonly" "--nginx"
"-d" "staging.{{company-name}}.talent.careers"
"-d" "{{company-name}}.talent.careers"
"-d" "talent.{{company-name}}.{{company-suffix}}"
"-d" "www.talent.{{company-name}}.{{company-suffix}}"
"--cert-name" "{{company-name}}"]))))
;; # 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"}])
(defn make-basic-dns-entries! [{:keys [company-name]}]
(let [uri "https://api.cloudflare.com/client/v4/zones/5cd643e7432d7cf69f44e268e32b5452/dns_records"
headers {"Authorization" (str "Bearer " (:token (vault/read-secret vault-client "secret/cloudflare-api")))}
entries (basic-dns-entries company-name)]
(debug "Creating DNS entries for" company-name "; Headers: " headers)
(doseq [entry entries]
(info (http/post uri
{:headers headers
:content-type :json
:form-params entry})))))
;; # Main initialization
(defn -main [& args]
(let [datamap {:company-name (nth args 0)
:company-suffix (nth args 1)}]
(vault/authenticate! vault-client :token (System/getenv "VAULT_TOKEN"))
(info "Creating deploy directories.")
(make-dirs! datamap)
(info "Creating basic DNS entries.")
(make-basic-dns-entries! datamap)
(info "Creating nginx entries.")
(create-nginx-server! datamap)
(info "Generating certificates.")
(generate-certs! datamap)
(info "Done.")))