Skip to content

Commit

Permalink
(PDB-5712) client: restore puppet client for command posts
Browse files Browse the repository at this point in the history
Use the new :post option to only post via the JDK client from
benchmark because we use the submit-* functions in both pdb and pdbext
tests, and those cause fips tests to fail with the current JDK client
configuration, e.g.:

  actual: java.lang.InternalError:
  java.security.NoSuchAlgorithmException: Unable to invoke creator for
  DEFAULT: Default key/trust managers unavailable

This should restore the puppet http client as of
6fc7da1 (just before the switch to
the JDK client in dc2033c) as the
default client for command submission.
  • Loading branch information
rbrw committed Oct 17, 2023
1 parent 81d898b commit 492727f
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 56 deletions.
64 changes: 61 additions & 3 deletions src/puppetlabs/puppetdb/cli/benchmark.clj
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,62 @@
[puppetlabs.puppetdb.nio :refer [get-path]])
(:import
(clojure.core.async.impl.protocols Buffer UnblockingBuffer)
(com.puppetlabs.ssl_utils SSLUtils)
(java.net URI)
(java.net.http HttpClient
HttpRequest
HttpRequest$Builder
HttpRequest$BodyPublishers
HttpResponse$BodyHandlers)
(java.nio.file.attribute FileAttribute)
(java.nio.file Files OpenOption)
(java.util ArrayDeque)
(java.util.concurrent RejectedExecutionException)))

(defn- ssl-info->context
[& {:keys [ssl-cert ssl-key ssl-ca-cert]}]
(SSLUtils/pemsToSSLContext (io/reader ssl-cert)
(io/reader ssl-key)
(io/reader ssl-ca-cert)))

(defn- build-http-client [& {:keys [ssl-cert] :as opts}]
(cond-> (HttpClient/newBuilder)
;; To follow redirects: (.followRedirects HttpClient$Redirect/NORMAL)
ssl-cert (.sslContext (ssl-info->context opts))
true .build))

;; Until we require requests to provide the client (perhaps we should)
(def ^:private http-client (memoize build-http-client))

(defn- json-request-generator
([uri] (.uri ^java.net.http.HttpRequest$Builder (json-request-generator) uri))
([] (-> (HttpRequest/newBuilder)
;; To follow redirects: (.followRedirects HttpClient$Redirect/NORMAL)
(.header "Content-Type" "application/json; charset=UTF-8")
(.header "Accept" "application/json"))))

(defn- string-publisher [s] (HttpRequest$BodyPublishers/ofString s))
(defn- string-handler [] (HttpResponse$BodyHandlers/ofString))

(defn- post-body
[^HttpClient client
^HttpRequest$Builder req-generator
body-publisher
response-body-handler]
(let [res (.send client (-> req-generator (.POST body-publisher) .build)
response-body-handler)]
;; Currently minimal
{::jdk-response res
:status (.statusCode res)}))

(defn- post-json-via-jdk [url body opts]
;; Unlisted, valid keys: ssl-cert ssl-key ssl-ca-cert
;; Intentionally ignores unrecognized keys
(post-body (http-client (select-keys opts [:ssl-cert :ssl-key :ssl-ca-cert]))
(json-request-generator (URI. url))
(string-publisher body)
(string-handler)))

(defn try-load-file
"Attempt to read and parse the JSON in `file`. If this failed, an error is
logged, and nil is returned."
Expand Down Expand Up @@ -298,6 +349,13 @@

(def random-cmd-delay safe-sample-normal)

(defn send-facts [url certname version catalog opts]
(client/submit-facts url certname version catalog (assoc opts :post post-json-via-jdk)))
(defn send-catalog [url certname version catalog opts]
(client/submit-catalog url certname version catalog (assoc opts :post post-json-via-jdk)))
(defn send-report [url certname version catalog opts]
(client/submit-report url certname version catalog (assoc opts :post post-json-via-jdk)))

(defn start-command-sender
"Start a command sending process in the background. Reads host-state maps from
command-send-ch and sends commands to the puppetdb at base-url. Writes
Expand Down Expand Up @@ -338,9 +396,9 @@
rate-monitor-ch
(map (fn [[command host version payload]]
(let [submit-fn (case command
:catalog client/submit-catalog
:report client/submit-report
:factset client/submit-facts)]
:factset send-facts
:catalog send-catalog
:report send-report)]
(try
(submit-fn base-url host version payload ssl-opts)
::submitted
Expand Down
68 changes: 15 additions & 53 deletions src/puppetlabs/puppetdb/client.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,78 +3,40 @@
[clojure.java.io :as io]
[clojure.set :as set]
[clojure.tools.logging :as log]
[puppetlabs.http.client.sync :as pclient]
[puppetlabs.http.client.sync :as http]
[puppetlabs.puppetdb.command.constants :refer [command-names]]
[puppetlabs.puppetdb.cheshire :as json]
[puppetlabs.puppetdb.schema :refer [defn-validated]]
[puppetlabs.puppetdb.time :as t]
[puppetlabs.puppetdb.utils :as utils]
[schema.core :as s])
(:import
(com.puppetlabs.ssl_utils SSLUtils)
(java.net HttpURLConnection URI)
(java.net.http HttpClient
HttpRequest
HttpRequest$Builder
HttpRequest$BodyPublishers
HttpResponse$BodyHandlers)))
(java.net HttpURLConnection)))

(def ^:private warn-on-reflection-orig *warn-on-reflection*)
(set! *warn-on-reflection* true)

(defn- ssl-info->context
[& {:keys [ssl-cert ssl-key ssl-ca-cert]}]
(SSLUtils/pemsToSSLContext (io/reader ssl-cert)
(io/reader ssl-key)
(io/reader ssl-ca-cert)))

(defn- build-http-client [& {:keys [ssl-cert] :as opts}]
(cond-> (HttpClient/newBuilder)
;; To follow redirects: (.followRedirects HttpClient$Redirect/NORMAL)
ssl-cert (.sslContext (ssl-info->context opts))
true .build))

;; Until we require requests to provide the client (perhaps we should)
(def ^:private http-client (memoize build-http-client))

(defn- json-request-generator
([uri] (.uri ^java.net.http.HttpRequest$Builder (json-request-generator) uri))
([] (-> (HttpRequest/newBuilder)
;; To follow redirects: (.followRedirects HttpClient$Redirect/NORMAL)
(.header "Content-Type" "application/json; charset=UTF-8")
(.header "Accept" "application/json"))))

(defn- string-publisher [s] (HttpRequest$BodyPublishers/ofString s))
(defn- string-handler [] (HttpResponse$BodyHandlers/ofString))

(defn- post-body
[^HttpClient client
^HttpRequest$Builder req-generator
body-publisher
response-body-handler]
(let [res (.send client (-> req-generator (.POST body-publisher) .build)
response-body-handler)]
;; Currently minimal
{::jdk-response res
:status (.statusCode res)}))

(defn get-metric [base-url metric-name]
(let [url (str (utils/base-url->str base-url)
"/mbeans/"
(java.net.URLEncoder/encode ^String metric-name "UTF-8"))]

(:body (pclient/get url {:throw-exceptions false
:content-type :json
:character-encoding "UTF-8"
:accept :json}))) )
(:body (http/get url {:throw-exceptions false
:content-type :json
:character-encoding "UTF-8"
:accept :json}))) )

(defn- post-json-string [url body opts]
;; Unlisted, valid keys: ssl-cert ssl-key ssl-ca-cert
;; Intentionally ignores unrecognized keys
(post-body (http-client (select-keys opts [:ssl-cert :ssl-key :ssl-ca-cert]))
(json-request-generator (URI. url))
(string-publisher body)
(string-handler)))
;;
;; This client is currently much slower than the JDK's (which we now
;; use in benchmark -- discovered while testing with large servers),
;; but we need it because the current benchmark client's
;; configuration won't work with fips.
(http/post url (merge {:body body
:as :text
:headers {"Content-Type" "application/json"}}
(select-keys opts [:ssl-cert :ssl-key :ssl-ca-cert]))))

(defn submit-command-via-http!
"Submits `payload` as a valid command of type `command` and
Expand Down

0 comments on commit 492727f

Please sign in to comment.