I wrote a hacky babashka script that extracts all the http requests to the google cloud api from terraform. This way I can see how terraform sets up a google cloud project and learn how I can do it myself using babashka and direct google cloud http requests
# first collect all output in the shell to file
TF_LOG=debug terraform apply -auto-approve -no-color &> apply.txt
then in babashka extract all requests
(def requests
(->> (slurp "apply.txt")
(re-seq #"(?s)---\[ REQUEST \]-{39}(.*?)-{53}" )
(map #(second %))
(map (fn [lines]
(->> lines
(clojure.string/split-lines)
(map (fn [line] (second (clojure.string/split line #"0_x5: " )))) ; you might need to modify 0_x5
(remove nil?)
(map (fn [line]
(let [[_ method url] (re-find #"^(POST|GET|PUT) (.*?) HTTP" line)
[_ hk hv] (re-find #"^([a-zA-Z-]*?): (.*?)$" line)
]
(cond (some? method) [:method-and-url method url]
(some? hk) [:header [hk hv]]
:else [:body line]
) )
))
(reduce (fn [acc [k v1 v2]]
(condp = k
:method-and-url (merge acc {:method v1 :url v2})
:header (merge acc {:headers (conj (:headers acc) v1 v2)})
:body (merge acc {:body (str (:body acc) v1 "\n")})
acc)
) {:headers {} :body "" :method "" :url ""})
)))))
; write to edn file for reference
(clojure.pprint/pprint requests (<http://clojure.java.io/writer|clojure.java.io/writer> "apply2.edn")
neat!!!
Also working on some functions to easily interact with google cloud from babashka
It's a work in progress. But this is how it looks like
(def headers
{"Accept" "application/json"
"Content-Type" "application/json"
"Authorization"
(str "Bearer "
(clojure.string/trim (:out (sh "gcloud" "beta" "auth" "application-default" "print-access-token"))))})
(defn to-kebab [inp]
(-> inp
(s/replace #"([A-Z0-9])([A-Z])" "$1-$2")
(s/replace #"([a-z0-9])([A-Z])" "$1-$2")
(s/replace #"[\s_]+", "-")
(s/lower-case)
keyword))
(defn to-camel-case-name [inp]
(-> inp
name
(s/replace #"-(\w)" #(s/upper-case (second %1)))))
(def hosts
{:crm "<http://cloudresourcemanager.googleapis.com|cloudresourcemanager.googleapis.com>"
:iam "<http://iam.googleapis.com|iam.googleapis.com>"
:sql "<http://sqladmin.googleapis.com|sqladmin.googleapis.com>"
:run "<http://us-east1-run.googleapis.com|us-east1-run.googleapis.com>"
:use "<http://serviceusage.googleapis.com|serviceusage.googleapis.com>"
:bill "<http://cloudbilling.googleapis.com|cloudbilling.googleapis.com>"
:sec "<http://secretmanager.googleapis.com|secretmanager.googleapis.com>" })
(defn url [api & paths]
(str "https://"
(get hosts api) "/"
(clojure.string/join "/" paths)))
(defn purl [api & paths]
(apply url (concat [api "v1" "projects"] paths)))
(def knative-apis
{:serving "serving.knative.dev"
:domains "<http://domains.cloudrun.com|domains.cloudrun.com>"})
(defn kurl [api & paths]
(apply url (concat [:run "apis" (get knative-apis api) "v1" ] paths)))
(defn api [opts method url & [params]]
(let [body (-> params :body)
conv (or (:convert-keys opts) false)
_ (clojure.pprint/pprint [method params] (io/writer (str "req.edn")))
res (apply
(condp method = :get curl/get :post curl/post :put curl/put)
[url
(merge
{:headers headers
:throw false}
params
(when
(map? body)
{:body
(-> body
(json/generate-string
(if conv {:key-fn to-camel-case-name} {})))}))])
_ (clojure.pprint/pprint res (io/writer (str "res.edn")))
body (-> res :body (json/parse-string (if conv to-kebab true)))]
(clojure.pprint/pprint body (io/writer (str "body.edn")))
body))
(def gc (partial api {:convert-keys true}))
(def kn (partial api {:convert-keys false}))
(def project-id "shed-suite-classic-auth")
; services activated on the project
(gc :get
(purl :use project-id "services")
{:query-params {"fields" "services/name,nextPageToken"
"filter" "state:ENABLED"}})
get all service accounts for instance
(gc :get (purl :crm project-id "serviceAccounts"))
Input and output keys get converted from and to kebab case. so it's more idiomatic clojure. request / response and body get written to edn files for testing purposes
Can't do the kebab conversion for knative / cloud run because that would mess up the manifest files