diff --git a/src/main/cljc/dda/k8s_keycloak/core.cljc b/src/main/cljc/dda/k8s_keycloak/core.cljc index e3b95c8..352e0ed 100644 --- a/src/main/cljc/dda/k8s_keycloak/core.cljc +++ b/src/main/cljc/dda/k8s_keycloak/core.cljc @@ -1,62 +1,19 @@ (ns dda.k8s-keycloak.core (:require - [clojure.string :as cs] + [clojure.string :as cs] [clojure.spec.alpha :as s] #?(:clj [orchestra.core :refer [defn-spec]] :cljs [orchestra.core :refer-macros [defn-spec]]) - [dda.k8s-keycloak.yaml :as yaml] - [dda.k8s-keycloak.common :as cm] - [dda.k8s-keycloak.postgres :as pg])) + [dda.k8s-keycloak.yaml :as yaml] + [dda.k8s-keycloak.keycloak :as kc] + [dda.k8s-keycloak.postgres :as pg])) -(s/def ::keycloak-admin-user cm/bash-env-string?) -(s/def ::keycloak-admin-password cm/bash-env-string?) -(s/def ::fqdn cm/fqdn-string?) -(s/def ::issuer cm/letsencrypt-issuer?) +(def config? (s/keys :req-un [::kc/fqdn] + :opt-un [::kc/issuer])) -(def config? (s/keys :req-un [::fqdn] - :opt-un [::issuer])) - -(def auth? (s/keys :req-un [::keycloak-admin-user ::keycloak-admin-password +(def auth? (s/keys :req-un [::kc/keycloak-admin-user ::kc/keycloak-admin-password ::pg/postgres-db-user ::pg/postgres-db-password])) -(defn generate-config [my-config my-auth] - (-> - (yaml/from-string (yaml/load-resource "keycloak/config.yaml")) - (assoc-in [:data :config.edn] (str my-config)) - (assoc-in [:data :credentials.edn] (str my-auth)))) - -(defn generate-deployment [my-auth] - (let [{:keys [postgres-db-user postgres-db-password - keycloak-admin-user keycloak-admin-password]} my-auth] - (-> - (yaml/from-string (yaml/load-resource "keycloak/deployment.yaml")) - (cm/replace-named-value "KEYCLOAK_USER" keycloak-admin-user) - (cm/replace-named-value "DB_USER" postgres-db-user) - (cm/replace-named-value "DB_PASSWORD" postgres-db-password) - (cm/replace-named-value "KEYCLOAK_PASSWORD" keycloak-admin-password)))) - -(defn generate-certificate [config] - (let [{:keys [fqdn issuer] - :or {issuer :staging}} config - letsencrypt-issuer (str "letsencrypt-" (name issuer) "-issuer")] - (-> - (yaml/from-string (yaml/load-resource "keycloak/certificate.yaml")) - (assoc-in [:spec :commonName] fqdn) - (assoc-in [:spec :dnsNames] [fqdn]) - (assoc-in [:spec :issuerRef :name] letsencrypt-issuer)))) - -(defn generate-ingress [config] - (let [{:keys [fqdn issuer] - :or {issuer :staging}} config - letsencrypt-issuer (str "letsencrypt-" (name issuer) "-issuer")] - (-> - (yaml/from-string (yaml/load-resource "keycloak/ingress.yaml")) - (assoc-in [:metadata :annotations :cert-manager.io/cluster-issuer] letsencrypt-issuer) - (cm/replace-all-matching-values-by-new-value "fqdn" fqdn)))) - -(defn generate-service [] - (yaml/from-string (yaml/load-resource "keycloak/service.yaml"))) - (defn-spec generate any? [my-config config? my-auth auth?] @@ -69,12 +26,12 @@ "---" (yaml/to-string (pg/generate-deployment)) "---" - (yaml/to-string (generate-config my-config my-auth)) + (yaml/to-string (kc/generate-secret my-auth)) "---" - (yaml/to-string (generate-certificate my-config)) + (yaml/to-string (kc/generate-certificate my-config)) "---" - (yaml/to-string (generate-ingress my-config)) + (yaml/to-string (kc/generate-ingress my-config)) "---" - (yaml/to-string (generate-service)) + (yaml/to-string (kc/generate-service)) "---" - (yaml/to-string (generate-deployment my-auth))])) \ No newline at end of file + (yaml/to-string (kc/generate-deployment))])) diff --git a/src/main/cljc/dda/k8s_keycloak/keycloak.cljc b/src/main/cljc/dda/k8s_keycloak/keycloak.cljc new file mode 100644 index 0000000..62be864 --- /dev/null +++ b/src/main/cljc/dda/k8s_keycloak/keycloak.cljc @@ -0,0 +1,43 @@ +(ns dda.k8s-keycloak.keycloak + (:require + [clojure.spec.alpha :as s] + [dda.k8s-keycloak.yaml :as yaml] + [dda.k8s-keycloak.base64 :as b64] + [dda.k8s-keycloak.common :as cm])) + +(s/def ::keycloak-admin-user cm/bash-env-string?) +(s/def ::keycloak-admin-password cm/bash-env-string?) +(s/def ::fqdn cm/fqdn-string?) +(s/def ::issuer cm/letsencrypt-issuer?) + +(defn generate-secret [my-auth] + (let [{:keys [keycloak-admin-user keycloak-admin-password]} my-auth] + (-> + (yaml/from-string (yaml/load-resource "keycloak/secret.yaml")) + (cm/replace-key-value :keycloak-user (b64/encode keycloak-admin-user)) + (cm/replace-key-value :keycloak-password (b64/encode keycloak-admin-password))))) + +(defn generate-deployment [] + (yaml/from-string (yaml/load-resource "keycloak/deployment.yaml"))) + +(defn generate-certificate [config] + (let [{:keys [fqdn issuer] + :or {issuer :staging}} config + letsencrypt-issuer (str "letsencrypt-" (name issuer) "-issuer")] + (-> + (yaml/from-string (yaml/load-resource "keycloak/certificate.yaml")) + (assoc-in [:spec :commonName] fqdn) + (assoc-in [:spec :dnsNames] [fqdn]) + (assoc-in [:spec :issuerRef :name] letsencrypt-issuer)))) + +(defn generate-ingress [config] + (let [{:keys [fqdn issuer] + :or {issuer :staging}} config + letsencrypt-issuer (str "letsencrypt-" (name issuer) "-issuer")] + (-> + (yaml/from-string (yaml/load-resource "keycloak/ingress.yaml")) + (assoc-in [:metadata :annotations :cert-manager.io/cluster-issuer] letsencrypt-issuer) + (cm/replace-all-matching-values-by-new-value "fqdn" fqdn)))) + +(defn generate-service [] + (yaml/from-string (yaml/load-resource "keycloak/service.yaml"))) diff --git a/src/main/resources/config.yaml b/src/main/resources/config.yaml deleted file mode 100755 index 1ba709e..0000000 --- a/src/main/resources/config.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: keycloak - labels: - app.kubernetes.io/name: k8s-keycloak -data: - config.edn: | - some-config-value - credentials.edn: | - some-credentials-value diff --git a/src/main/resources/keycloak/config.yaml b/src/main/resources/keycloak/config.yaml deleted file mode 100755 index 1ba709e..0000000 --- a/src/main/resources/keycloak/config.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: keycloak - labels: - app.kubernetes.io/name: k8s-keycloak -data: - config.edn: | - some-config-value - credentials.edn: | - some-credentials-value diff --git a/src/main/resources/keycloak/deployment.yaml b/src/main/resources/keycloak/deployment.yaml index 56bcfd2..0c677cb 100644 --- a/src/main/resources/keycloak/deployment.yaml +++ b/src/main/resources/keycloak/deployment.yaml @@ -23,20 +23,35 @@ spec: value: POSTGRES - name: DB_ADDR value: postgresql-service - - name: DB_DATABASE - value: keycloak - - name: DB_USER - value: keycloak - name: DB_SCHEMA value: public + - name: DB_DATABASE + valueFrom: + configMapKeyRef: + name: postgres-config + key: postgres-db + - name: DB_USER + valueFrom: + secretKeyRef: + name: postgres-secret + key: postgres-user - name: DB_PASSWORD - value: password - - name: KEYCLOAK_USER - value: admin - - name: KEYCLOAK_PASSWORD - value: admin + valueFrom: + secretKeyRef: + name: postgres-secret + key: postgres-password - name: PROXY_ADDRESS_FORWARDING value: "true" + - name: KEYCLOAK_USER + valueFrom: + secretKeyRef: + name: keycloak-secret + key: keycloak-user + - name: KEYCLOAK_PASSWORD + valueFrom: + secretKeyRef: + name: keycloak-secret + key: keycloak-password ports: - name: http containerPort: 8080 diff --git a/src/main/resources/keycloak/secret.yaml b/src/main/resources/keycloak/secret.yaml new file mode 100644 index 0000000..43d0adc --- /dev/null +++ b/src/main/resources/keycloak/secret.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: keycloak-secret +type: Opaque +data: + keycloak-user: admin + keycloak-password: admin diff --git a/src/test/cljc/dda/k8s_keycloak/core_test.cljc b/src/test/cljc/dda/k8s_keycloak/keycloak_test.cljc similarity index 67% rename from src/test/cljc/dda/k8s_keycloak/core_test.cljc rename to src/test/cljc/dda/k8s_keycloak/keycloak_test.cljc index 9c49b6d..72f0b80 100644 --- a/src/test/cljc/dda/k8s_keycloak/core_test.cljc +++ b/src/test/cljc/dda/k8s_keycloak/keycloak_test.cljc @@ -1,16 +1,18 @@ -(ns dda.k8s-keycloak.core-test +(ns dda.k8s-keycloak.keycloak-test (:require #?(:clj [clojure.test :refer [deftest is are testing run-tests]] :cljs [cljs.test :refer-macros [deftest is are testing run-tests]]) - [dda.k8s-keycloak.core :as cut])) + [dda.k8s-keycloak.keycloak :as cut])) -(deftest should-generate-yaml - (is (= {:apiVersion "v1", :kind "ConfigMap" - :metadata {:name "keycloak", - :labels {:app.kubernetes.io/name "k8s-keycloak"}}, - :data {:config.edn "some-config-value\n", - :credentials.edn "some-credentials-value\n"}} - (cut/generate-config "some-config-value\n" "some-credentials-value\n")))) +(deftest should-generate-secret + (is (= {:apiVersion "v1" + :kind "Secret" + :metadata {:name "keycloak-secret"} + :type "Opaque" + :data + {:keycloak-user "dXNlcg==" + :keycloak-password "cGFzc3dvcmQ="}} + (cut/generate-secret {:keycloak-admin-user "user" :keycloak-admin-password "password"})))) (deftest should-generate-certificate (is (= {:apiVersion "cert-manager.io/v1alpha2" @@ -65,7 +67,10 @@ (deftest should-generate-deployment (is (= {:apiVersion "apps/v1" :kind "Deployment" - :metadata {:name "keycloak", :namespace "default", :labels {:app "keycloak"}} + :metadata + {:name "keycloak" + :namespace "default" + :labels {:app "keycloak"}} :spec {:replicas 1 :selector {:matchLabels {:app "keycloak"}} @@ -78,14 +83,32 @@ :env [{:name "DB_VENDOR", :value "POSTGRES"} {:name "DB_ADDR", :value "postgresql-service"} - {:name "DB_DATABASE", :value "keycloak"} - {:name "DB_USER", :value "db-user"} {:name "DB_SCHEMA", :value "public"} - {:name "DB_PASSWORD", :value "db-password"} - {:name "KEYCLOAK_USER", :value "testuser"} - {:name "KEYCLOAK_PASSWORD", :value "test1234"} - {:name "PROXY_ADDRESS_FORWARDING", :value "true"}] + {:name "DB_DATABASE" + :valueFrom + {:configMapKeyRef + {:name "postgres-config", :key "postgres-db"}}} + {:name "DB_USER" + :valueFrom + {:secretKeyRef + {:name "postgres-secret", :key "postgres-user"}}} + {:name "DB_PASSWORD" + :valueFrom + {:secretKeyRef + {:name "postgres-secret" + :key "postgres-password"}}} + {:name "PROXY_ADDRESS_FORWARDING", :value "true"} + {:name "KEYCLOAK_USER" + :valueFrom + {:secretKeyRef + {:name "keycloak-secret", :key "keycloak-user"}}} + {:name "KEYCLOAK_PASSWORD" + :valueFrom + {:secretKeyRef + {:name "keycloak-secret" + :key "keycloak-password"}}}] :ports [{:name "http", :containerPort 8080}] - :readinessProbe {:httpGet {:path "/auth/realms/master", :port 8080}}}]}}}} - (cut/generate-deployment {:keycloak-admin-user "testuser" :keycloak-admin-password "test1234" - :postgres-db-user "db-user" :postgres-db-password "db-password"})))) + :readinessProbe + {:httpGet + {:path "/auth/realms/master", :port 8080}}}]}}}} + (cut/generate-deployment)))) diff --git a/src/test/cljc/dda/k8s_keycloak/yaml_test.cljc b/src/test/cljc/dda/k8s_keycloak/yaml_test.cljc index a348c3b..838b5a5 100644 --- a/src/test/cljc/dda/k8s_keycloak/yaml_test.cljc +++ b/src/test/cljc/dda/k8s_keycloak/yaml_test.cljc @@ -14,9 +14,32 @@ (cut/to-string {:hallo "welt"})))) (deftest should-convert-config-yml-to-map - (is (= {:apiVersion "v1", :kind "ConfigMap" - :metadata {:name "keycloak", - :labels {:app.kubernetes.io/name "k8s-keycloak"}}, - :data {:config.edn "some-config-value\n", - :credentials.edn "some-credentials-value\n"}} - (cut/from-string (cut/load-resource "config.yaml"))))) + (is (= {:apiVersion "networking.k8s.io/v1beta1" + :kind "Ingress" + :metadata + {:name "ingress-cloud" + :annotations + {:cert-manager.io/cluster-issuer + "letsencrypt-staging-issuer" + :nginx.ingress.kubernetes.io/proxy-body-size "256m" + :nginx.ingress.kubernetes.io/ssl-redirect "true" + :nginx.ingress.kubernetes.io/rewrite-target "/" + :nginx.ingress.kubernetes.io/proxy-connect-timeout "300" + :nginx.ingress.kubernetes.io/proxy-send-timeout "300" + :nginx.ingress.kubernetes.io/proxy-read-timeout "300"} + :namespace "default"} + :spec + {:tls [{:hosts ["fqdn"], :secretName "keycloak-secret"}] + :rules + [{:host "fqdn" + :http + {:paths + [{:backend + {:serviceName "keycloak", :servicePort 8080}}]}} + {:host "fqdn" + :http + {:paths + [{:backend + {:serviceName "another_keycloak" + :servicePort 8081}}]}}]}} + (cut/from-string (cut/load-resource "ingress_test.yaml")))))