add secret & config refs to keycloak

This commit is contained in:
jem 2021-06-01 21:32:07 +02:00
parent 2d3f50d2a9
commit 444cb32554
8 changed files with 158 additions and 111 deletions

View file

@ -5,58 +5,15 @@
#?(:clj [orchestra.core :refer [defn-spec]] #?(:clj [orchestra.core :refer [defn-spec]]
:cljs [orchestra.core :refer-macros [defn-spec]]) :cljs [orchestra.core :refer-macros [defn-spec]])
[dda.k8s-keycloak.yaml :as yaml] [dda.k8s-keycloak.yaml :as yaml]
[dda.k8s-keycloak.common :as cm] [dda.k8s-keycloak.keycloak :as kc]
[dda.k8s-keycloak.postgres :as pg])) [dda.k8s-keycloak.postgres :as pg]))
(s/def ::keycloak-admin-user cm/bash-env-string?) (def config? (s/keys :req-un [::kc/fqdn]
(s/def ::keycloak-admin-password cm/bash-env-string?) :opt-un [::kc/issuer]))
(s/def ::fqdn cm/fqdn-string?)
(s/def ::issuer cm/letsencrypt-issuer?)
(def config? (s/keys :req-un [::fqdn] (def auth? (s/keys :req-un [::kc/keycloak-admin-user ::kc/keycloak-admin-password
:opt-un [::issuer]))
(def auth? (s/keys :req-un [::keycloak-admin-user ::keycloak-admin-password
::pg/postgres-db-user ::pg/postgres-db-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? (defn-spec generate any?
[my-config config? [my-config config?
my-auth auth?] my-auth auth?]
@ -69,12 +26,12 @@
"---" "---"
(yaml/to-string (pg/generate-deployment)) (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))])) (yaml/to-string (kc/generate-deployment))]))

View file

@ -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")))

View file

@ -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

View file

@ -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

View file

@ -23,20 +23,35 @@ spec:
value: POSTGRES value: POSTGRES
- name: DB_ADDR - name: DB_ADDR
value: postgresql-service value: postgresql-service
- name: DB_DATABASE
value: keycloak
- name: DB_USER
value: keycloak
- name: DB_SCHEMA - name: DB_SCHEMA
value: public 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 - name: DB_PASSWORD
value: password valueFrom:
- name: KEYCLOAK_USER secretKeyRef:
value: admin name: postgres-secret
- name: KEYCLOAK_PASSWORD key: postgres-password
value: admin
- name: PROXY_ADDRESS_FORWARDING - name: PROXY_ADDRESS_FORWARDING
value: "true" 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: ports:
- name: http - name: http
containerPort: 8080 containerPort: 8080

View file

@ -0,0 +1,8 @@
apiVersion: v1
kind: Secret
metadata:
name: keycloak-secret
type: Opaque
data:
keycloak-user: admin
keycloak-password: admin

View file

@ -1,16 +1,18 @@
(ns dda.k8s-keycloak.core-test (ns dda.k8s-keycloak.keycloak-test
(:require (:require
#?(:clj [clojure.test :refer [deftest is are testing run-tests]] #?(:clj [clojure.test :refer [deftest is are testing run-tests]]
:cljs [cljs.test :refer-macros [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 (deftest should-generate-secret
(is (= {:apiVersion "v1", :kind "ConfigMap" (is (= {:apiVersion "v1"
:metadata {:name "keycloak", :kind "Secret"
:labels {:app.kubernetes.io/name "k8s-keycloak"}}, :metadata {:name "keycloak-secret"}
:data {:config.edn "some-config-value\n", :type "Opaque"
:credentials.edn "some-credentials-value\n"}} :data
(cut/generate-config "some-config-value\n" "some-credentials-value\n")))) {:keycloak-user "dXNlcg=="
:keycloak-password "cGFzc3dvcmQ="}}
(cut/generate-secret {:keycloak-admin-user "user" :keycloak-admin-password "password"}))))
(deftest should-generate-certificate (deftest should-generate-certificate
(is (= {:apiVersion "cert-manager.io/v1alpha2" (is (= {:apiVersion "cert-manager.io/v1alpha2"
@ -65,7 +67,10 @@
(deftest should-generate-deployment (deftest should-generate-deployment
(is (= {:apiVersion "apps/v1" (is (= {:apiVersion "apps/v1"
:kind "Deployment" :kind "Deployment"
:metadata {:name "keycloak", :namespace "default", :labels {:app "keycloak"}} :metadata
{:name "keycloak"
:namespace "default"
:labels {:app "keycloak"}}
:spec :spec
{:replicas 1 {:replicas 1
:selector {:matchLabels {:app "keycloak"}} :selector {:matchLabels {:app "keycloak"}}
@ -78,14 +83,32 @@
:env :env
[{:name "DB_VENDOR", :value "POSTGRES"} [{:name "DB_VENDOR", :value "POSTGRES"}
{:name "DB_ADDR", :value "postgresql-service"} {:name "DB_ADDR", :value "postgresql-service"}
{:name "DB_DATABASE", :value "keycloak"}
{:name "DB_USER", :value "db-user"}
{:name "DB_SCHEMA", :value "public"} {:name "DB_SCHEMA", :value "public"}
{:name "DB_PASSWORD", :value "db-password"} {:name "DB_DATABASE"
{:name "KEYCLOAK_USER", :value "testuser"} :valueFrom
{:name "KEYCLOAK_PASSWORD", :value "test1234"} {:configMapKeyRef
{:name "PROXY_ADDRESS_FORWARDING", :value "true"}] {: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}] :ports [{:name "http", :containerPort 8080}]
:readinessProbe {:httpGet {:path "/auth/realms/master", :port 8080}}}]}}}} :readinessProbe
(cut/generate-deployment {:keycloak-admin-user "testuser" :keycloak-admin-password "test1234" {:httpGet
:postgres-db-user "db-user" :postgres-db-password "db-password"})))) {:path "/auth/realms/master", :port 8080}}}]}}}}
(cut/generate-deployment))))

View file

@ -14,9 +14,32 @@
(cut/to-string {:hallo "welt"})))) (cut/to-string {:hallo "welt"}))))
(deftest should-convert-config-yml-to-map (deftest should-convert-config-yml-to-map
(is (= {:apiVersion "v1", :kind "ConfigMap" (is (= {:apiVersion "networking.k8s.io/v1beta1"
:metadata {:name "keycloak", :kind "Ingress"
:labels {:app.kubernetes.io/name "k8s-keycloak"}}, :metadata
:data {:config.edn "some-config-value\n", {:name "ingress-cloud"
:credentials.edn "some-credentials-value\n"}} :annotations
(cut/from-string (cut/load-resource "config.yaml"))))) {: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")))))