Skip to content

Instantly share code, notes, and snippets.

@leifericf
Last active January 9, 2024 20:21
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leifericf/242fb222966c8cfc8beb04539aaf8fab to your computer and use it in GitHub Desktop.
Save leifericf/242fb222966c8cfc8beb04539aaf8fab to your computer and use it in GitHub Desktop.
Consuming 3rd Party APIs Using Clojure (Babashka)
{:paths ["src"]
:deps {org.babashka/json {:mvn/version "0.1.1"}}}
(ns pulumi
(:require [babashka.http-client :as http]
[babashka.json :as json]))
; Generic functions to perform HTTP requests.
(defn fetch
"Perform an HTTP request, injecting a continuation key if supplied."
[request & [cont-key]]
(-> (:request request)
(cond-> cont-key
(assoc-in [:query-params (get-in request [:page :key-fn])] cont-key))
(http/request)
:body
(json/read-str keyword)))
(defn fetch-all
"Perform repeated HTTP requests using continuation keys."
[request]
(-> (iteration (partial fetch request)
:vf (get-in request [:page :val-fn])
:kf (get-in request [:page :key-fn]))
seq
flatten))
; Pulumi-specific HTTP request maps and functions to create them.
(def pulumi-uri "https://api.pulumi.com/api")
(def headers
{"Accept" "application/vnd.pulumi+8"
"Content-Type" "application/json"
"Authorization" (str "token " (System/getenv "PULUMI_ACCESS_TOKEN"))})
(def users
{:request {:headers headers
:uri (format (str pulumi-uri "/orgs/%s/members")
(System/getenv "PULUMI_ORG"))
:query-params {:type "backend"}
:method :get}
:page {:val-fn :members
:key-fn :continuationToken}})
(def teams
{:request {:headers headers
:uri (format (str pulumi-uri "/orgs/%s/teams")
(System/getenv "PULUMI_ORG"))
:method :get}
:page {:val-fn :teams
:key-fn :continuationToken}})
(def stacks
{:request {:headers headers
:uri (str pulumi-uri "/user/stacks")
:query-params {:organization (System/getenv "PULUMI_ORG")}
:method :get}
:page {:val-fn :stacks
:key-fn :continuationToken}})
(defn grant-permission
"Create request maps to grant a Team access to a Stack."
[team permission stack]
{:headers headers
:uri (format (str pulumi-uri "/orgs/%s/teams/%s")
(:orgName stack) team)
:body (-> {"addStackPermission"
{"projectName" (:projectName stack)
"stackName" (:stackName stack)
"permission" (permission {:read 101
:edit 102
:admin 103})}}
json/write-str)
:method :patch})
(comment
; Fetch the first page of Users.
(fetch users)
; Fetch *all* Users by using continuation tokens.
(fetch-all users)
; Fetch the first page of Teams.
(fetch teams)
; Fetch *all* Teams by using continuation tokens.
(fetch-all teams)
; Fetch the first page of Stacks.
(fetch stacks)
; Fetch *all* Stacks by using continuation tokens.
(fetch-all stacks)
; Grant a Team permission to desired Stacks by un-commenting/adjusting the filter.
(doall
(->> (fetch-all stacks)
; (filter #(and (= "project-name" (:projectName %))
; (= "stack-name" (:stackName %))))
(map #(grant-permission "TEAM_NAME" :read %))
(pmap http/request)
(keep :status))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment