diff --git a/src/ziggurat/config.clj b/src/ziggurat/config.clj index 9db7afaf..663ed020 100644 --- a/src/ziggurat/config.clj +++ b/src/ziggurat/config.clj @@ -6,7 +6,8 @@ [mount.core :refer [defstate]] [ziggurat.util.java-util :as util]) (:import (java.util Properties) - [org.apache.kafka.common.config SaslConfigs]) + [org.apache.kafka.common.config SaslConfigs] + [org.apache.kafka.clients CommonClientConfigs]) (:gen-class :methods [^{:static true} [get [String] Object] @@ -95,6 +96,9 @@ (defn ssl-config [] (get-in config [:ziggurat :ssl])) +(defn sasl-config [] + (get-in config [:ziggurat :sasl])) + (defn rabbitmq-config [] (get (ziggurat-config) :rabbit-mq)) @@ -197,24 +201,27 @@ (.setProperty p sk nv)))) p) -(def jaas-template - {"PLAIN" "org.apache.kafka.common.security.plain.PlainLoginModule" - "SCRAM-SHA-512" "org.apache.kafka.common.security.scram.ScramLoginModule"}) - (defn create-jaas-properties - [user-name password mechanism] - (let [jaas-template (get jaas-template mechanism)] - (format "%s required username=\"%s\" password=\"%s\";" jaas-template user-name password))) + [user-name password login-module] + (format "%s required username=\"%s\" password=\"%s\";" login-module user-name password)) (defn- add-jaas-properties [properties jaas-config] (if (some? jaas-config) (let [username (get jaas-config :username) password (get jaas-config :password) - mechanism (get jaas-config :mechanism)] + login-module (get jaas-config :login-module) + jaas_props (create-jaas-properties username password login-module)] (doto properties - (.put SaslConfigs/SASL_JAAS_CONFIG - (create-jaas-properties username password mechanism)))) + (.put SaslConfigs/SASL_JAAS_CONFIG jaas_props))) + properties)) + +(defn- add-sasl-properties + [properties mechanism protocol] + (if (and (some? mechanism) (some? protocol)) + (doto properties + (.put SaslConfigs/SASL_MECHANISM mechanism) + (.put CommonClientConfigs/SECURITY_PROTOCOL_CONFIG protocol)) properties)) (defn build-ssl-properties @@ -232,18 +239,53 @@ {:enabled true :ssl-keystore-location <> :ssl-keystore-password <> + :mechanism <> + :protocol <> {:jaas {:username <> :password <> - :mechanism <>}}} + :login-module <>}}} " (let [ssl-configs-enabled (:enabled ssl-config-map) - jaas-config (get ssl-config-map :jaas)] + jaas-config (get ssl-config-map :jaas) + mechanism (get ssl-config-map :mechanism) + protocol (get ssl-config-map :protocol)] (if (true? ssl-configs-enabled) (as-> properties pr (add-jaas-properties pr jaas-config) + (add-sasl-properties pr mechanism protocol) (reduce-kv set-property-fn pr ssl-config-map)) properties))) +(defn build-sasl-properties + [properties set-property-fn sasl-config-map] + "Builds SASL properties from sasl-config-map which is a map where keys are + Clojure keywords in kebab case. These keys are converted to Kafka properties by set-property-fn. + + SASL properties are only set if [:ziggurat :sasl :enabled] returns true. + + Creates JAAS template if values are provided in the map provided against this key sequence + [:ziggurat :sasl :jaas]. + + Example of sasl-config-map + {:enabled true + :protocol <> + :mechanism <> + {:jaas + {:username <> + :password <> + :login-module <>}}} + " + (let [sasl-configs-enabled (:enabled sasl-config-map) + jaas-config (get sasl-config-map :jaas) + mechanism (get sasl-config-map :mechanism) + protocol (get sasl-config-map :protocol)] + (if (true? sasl-configs-enabled) + (as-> properties pr + (add-jaas-properties pr jaas-config) + (add-sasl-properties pr mechanism protocol) + (reduce-kv set-property-fn pr sasl-config-map)) + properties))) + (defn build-properties "Builds Properties object from the provided config-map which is a map where keys are Clojure keywords in kebab case. These keys are converted to Kafka properties by set-property-fn. @@ -265,6 +307,7 @@ [set-property-fn config-map] (as-> (Properties.) pr (build-ssl-properties pr set-property-fn (ssl-config)) + (build-sasl-properties pr set-property-fn (sasl-config)) (reduce-kv set-property-fn pr config-map))) (def build-consumer-config-properties diff --git a/test/ziggurat/config_test.clj b/test/ziggurat/config_test.clj index 1337bdd4..581056df 100644 --- a/test/ziggurat/config_test.clj +++ b/test/ziggurat/config_test.clj @@ -21,6 +21,7 @@ statsd-config ziggurat-config ssl-config + sasl-config create-jaas-properties]] [ziggurat.fixtures :as f]) (:import (java.util ArrayList Properties))) @@ -321,9 +322,10 @@ (with-redefs [ssl-config (constantly {:enabled true :ssl-keystore-location "/some/location" :ssl-keystore-password "some-password" + :mechanism "SCRAM-SHA-512" :jaas {:username "myuser" :password "mypassword" - :mechanism "SCRAM-SHA-512"}})] + :login-module "org.apache.kafka.common.security.scram.ScramLoginModule"}})] (let [streams-config-map {:auto-offset-reset :latest} props (build-streams-config-properties streams-config-map) auto-offset-reset (.getProperty props "auto.offset.reset") @@ -333,7 +335,7 @@ (is (= auto-offset-reset "latest")) (is (= ssl-ks-location "/some/location")) (is (= ssl-ks-password "some-password")) - (is (= sasl-jaas-config (create-jaas-properties "myuser" "mypassword" "SCRAM-SHA-512")))))) + (is (= sasl-jaas-config (create-jaas-properties "myuser" "mypassword" "org.apache.kafka.common.security.scram.ScramLoginModule")))))) (testing "ssl properties DO NOT create jaas template if no value is provided for key sequence [:ziggurat :ssl :jaas]" (with-redefs [ssl-config (constantly {:enabled true :ssl-keystore-location "/some/location" @@ -347,7 +349,23 @@ (is (= auto-offset-reset "latest")) (is (= ssl-ks-location "/some/location")) (is (= ssl-ks-password "some-password")) - (is (nil? sasl-jaas-config))))))) + (is (nil? sasl-jaas-config))))) + (testing "sasl properties create jaas template from the map provided in [:ziggurat :sasl :jaas]" + (with-redefs [sasl-config (constantly {:enabled true + :protocol "SASL_PLAINTEXT" + :mechanism "SCRAM-SHA-256" + :jaas {:username "myuser" + :password "mypassword" + :login-module "org.apache.kafka.common.security.scram.ScramLoginModule"}})] + (let [streams-config-map {:auto-offset-reset :latest} + props (build-streams-config-properties streams-config-map) + auto-offset-reset (.getProperty props "auto.offset.reset") + sasl-jaas-config (.getProperty props "sasl.jaas.config") + sasl-protocol (.getProperty props "security.protocol") + sasl-mechanism (.getProperty props "sasl.mechanism")] + (is (= auto-offset-reset "latest")) + (is (= sasl-protocol "SASL_PLAINTEXT")) + (is (= sasl-jaas-config (create-jaas-properties "myuser" "mypassword" "org.apache.kafka.common.security.scram.ScramLoginModule")))))))) (deftest test-set-property (testing "set-property with empty (with spaces) value"