Skip to content

Instantly share code, notes, and snippets.

@lutter
Created September 16, 2015 19:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lutter/fd9171617dd44d382340 to your computer and use it in GitHub Desktop.
Save lutter/fd9171617dd44d382340 to your computer and use it in GitHub Desktop.
(ns user
(:require [puppetlabs.http.client.sync :as http]
[clojure.java.io :as io]
[cheshire.core :as json]))
(def dir "/home/lutter/code/deployer/LOCAL/puppet-master/ssl")
(def config
{
:ssl-config
{:ssl-cert (str dir "/certs/puppet-master.local.watzmann.net.pem")
:ssl-key (str dir "/private_keys/puppet-master.local.watzmann.net.pem")
:ssl-ca-cert (str dir "/certs/ca.pem")}
:classifier-service "https://puppet-master:4433/classifier-api/v1"
:puppetdb-service "https://puppet-master:8081/pdb/query/v4"
})
(defn- add-ssl-config
[params]
(if (not (:ssl-ca-cert params))
(merge params (:ssl-config config))
params))
(defn make-request
[method url params]
(try
(let [request (assoc (add-ssl-config params) :url url :method method)
{:keys [status body headers]} (http/request request)]
(cond
(not= 200 status)
(do
(println (format "%s %s: received bad status %d" method url status))
(if (re-find #"[jp]son" (or (headers "content-type") ""))
(println
(-> (io/reader body)
(json/parse-stream true)
(:message))
(slurp body)))
{})
:else
(-> body
(io/reader)
(json/parse-stream true))))
(catch Exception e
(println (format "%s %s: exception thrown" method url))
e)))
(defn get-request
"Make an HTTP GET request to URL using the parameters in PARAMS and parse
the JSON response.
Return an empty map on anything but a 200 response"
([url]
(get-request url {}))
([url params]
(make-request :get url params)))
(defn post-request
[url body]
(make-request :post url {:body (json/generate-string body)
:headers {"Content-Type" "application/json"}}))
;; Mapping between sexpr and nested JSON arrays
(defn sexpr->arrays
"Turn an sexpr into the equivalent JSON representation using nested arrays"
[sexpr]
(let [primitive->string
(fn [primitive]
(cond
(or (symbol? primitive)
(keyword? primitive)) (name primitive)
;; the NC doesn't like numbers in its queries
(number? primitive) (str primitive)
:else primitive))]
(if (sequential? sexpr)
(let [exprs (map sexpr->arrays (rest sexpr))]
(into [(primitive->string (first sexpr))] exprs))
(primitive->string sexpr))))
(defn arrays->sexpr
"Turn nested JSON arrays into an sexpr"
[arrays]
(letfn [(primitive->string [primitive]
(if (string? primitive)
(symbol primitive)
primitive))]
(if (sequential? arrays)
(map arrays->sexpr arrays)
(primitive->string arrays))))
;; Classifier functions
(defn nc-url
[path]
(str (:classifier-service config) path))
(defn nc-groups
([] (get-request (nc-url "/groups")))
([id] (get-request (nc-url (format "/groups/%s" id)))))
(defn nc-translate
"Send the SEXPR to the classifier to have it turn it into a PuppetDB query"
[sexpr]
(arrays->sexpr (post-request (nc-url "/rules/translate")
(sexpr->arrays sexpr))))
;; PuppetDB functions
(defn pdb-url
[path]
(str (:puppetdb-service config) path))
(defn pdb-nodes
"Query PuppetDB for a list of nodes using the given SEXPR"
[sexpr]
(get-request
(pdb-url "/nodes")
{:query (json/generate-string (sexpr->arrays sexpr))}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment