Compare commits

..

No commits in common. "kc-upgrade-and-integration" and "master" have entirely different histories.

7 changed files with 134 additions and 135 deletions

View file

@ -1,28 +0,0 @@
- ## Outline - Keycloak&Forgejo integration
- ### Forgejo-Seite
- Forgejo Test mit v8.0 hochziehen
- ### Config
- https://s3lph.me/ldap-to-oidc-migration-1-forgejo.html
- OpenID Connect Auto Discovery URL finden
- https://keycloak.discourse.group/t/changes-in-oidc-token-endpoints/18024/3
- `https://<full server dns name>/realms/<realm_name>`
- macht aber eine Zertifikatsprüfung -> tut nur mit prod zert
- key von keycloak eintragen
- forgejo-test user anlegen
- oidc auth source festlegen
- ## Keycloak-Seite
- Keycloak mit c4k/keycloak kc-upgrade-and-integration Branch hochziehen
- Admin login über keycloak.test.meissa.de/realms/master/account/
- [Getting started with kubernetes](https://www.keycloak.org/getting-started/getting-started-kube)
- Achtung URL für Userlogin ist <hostname>/realms/<realmname>/account
- Achtung: Pro realm angelegte user können sich auch nur pro realm einloggen
- Im master realm: https://keycloak.test.meissa.de/realms/master/account:
- Meissa realm anlegen
- "Forgejotest" user anlegen
- Forgejo-client anlegen
- Root url ist schema + hostname
- Client secret anlegen
- Schalter bei Client Authentication umlegen
- Capability config
- https://stackoverflow.com/questions/44752273/do-keycloak-clients-have-a-client-secret/69726692#69726692
- Keys anlegen und public key bei forgejo eintragen

View file

@ -19,9 +19,7 @@
:postgres-size :2gb
:db-name "keycloak"
:pv-storage-size-gb 30
:pvc-storage-class-name default-storage-class
:max-rate 100
:max-concurrent-requests 50})
:pvc-storage-class-name default-storage-class})
(def config? (s/keys :req-un [::kc/fqdn]
:opt-un [::kc/issuer
@ -40,10 +38,9 @@
(cm/concat-vec
(ns/generate config)
(postgres/generate-config config)
[(kc/generate-configmap config)
(kc/generate-service config)
[(kc/generate-service config)
(kc/generate-deployment config)]
(kc/generate-ratelimit-ingress config)
(kc/generate-ingress config)
(when (contains? config :mon-cfg)
(mon/generate-config))))))

View file

@ -11,18 +11,14 @@
[dda.c4k-common.predicate :as cp]))
(s/def ::fqdn cp/fqdn-string?)
(s/def ::issuer cp/letsencrypt-issuer?)
(s/def ::namespace string?)
(s/def ::max-rate int?)
(s/def ::max-concurrent-requests int?)
(s/def ::issuer cp/letsencrypt-issuer?)
(s/def ::keycloak-admin-user cp/bash-env-string?)
(s/def ::keycloak-admin-password cp/bash-env-string?)
(def config? (s/keys :req-un [::fqdn]
:opt-un [::issuer
::namespace
::max-rate
::max-concurrent-requests]))
::namespace]))
(def auth? (s/keys :req-un [::keycloak-admin-user
::keycloak-admin-password]))
@ -31,38 +27,25 @@
(defmethod yaml/load-resource :keycloak [resource-name]
(get (inline-resources "keycloak") resource-name)))
(defn-spec generate-ratelimit-ingress seq?
(defn-spec generate-ingress cp/map-or-seq?
[config config?]
(let [{:keys [fqdn max-rate max-concurrent-requests namespace]} config]
(ing/generate-simple-ingress (merge
(ing/generate-ingress-and-cert
(merge
{:service-name "keycloak"
:service-port 80
:fqdns [fqdn]
:average-rate max-rate
:burst-rate max-concurrent-requests
:namespace namespace}
config))))
:fqdns [(:fqdn config)]}
config)))
(defn-spec generate-secret cp/map-or-seq?
[config config?
auth auth?]
(let [{:keys [namespace]} config
{:keys [keycloak-admin-user keycloak-admin-password postgres-db-user postgres-db-password]} auth]
{:keys [keycloak-admin-user keycloak-admin-password]} auth]
(->
(yaml/load-as-edn "keycloak/secret.yaml")
(cm/replace-all-matching "NAMESPACE" namespace)
(cm/replace-all-matching "DBUSER" (b64/encode postgres-db-user))
(cm/replace-all-matching "DBPW" (b64/encode postgres-db-password))
(cm/replace-all-matching "ADMIN_USER" (b64/encode keycloak-admin-user))
(cm/replace-all-matching "ADMIN_PASS" (b64/encode keycloak-admin-password)))))
(defn-spec generate-configmap cp/map-or-seq?
[config config?]
(let [{:keys [namespace fqdn]} config]
(->
(yaml/load-as-edn "keycloak/configmap.yaml")
(cm/replace-all-matching "NAMESPACE" namespace)
(cm/replace-all-matching "FQDN" fqdn))))
(cm/replace-key-value :keycloak-user (b64/encode keycloak-admin-user))
(cm/replace-key-value :keycloak-password (b64/encode keycloak-admin-password)))))
(defn-spec generate-service cp/map-or-seq?
[config config?]
@ -76,5 +59,6 @@
(let [{:keys [fqdn namespace]} config]
(->
(yaml/load-as-edn "keycloak/deployment.yaml")
(cm/replace-all-matching "NAMESPACE" namespace))))
(cm/replace-all-matching "NAMESPACE" namespace)
(cm/replace-all-matching "FQDN" fqdn))))

View file

@ -1,22 +0,0 @@
# Hostname config:
# https://www.keycloak.org/server/hostname#_exposing_the_administration_console_on_a_separate_hostname
apiVersion: v1
kind: ConfigMap
metadata:
name: keycloak-env
namespace: NAMESPACE
data:
KC_HTTPS_CERTIFICATE_FILE: /etc/certs/tls.crt
KC_HTTPS_CERTIFICATE_KEY_FILE: /etc/certs/tls.key
# We trust our traefik to properly set headers
# see: https://www.keycloak.org/server/reverseproxy & https://www.keycloak.org/server/hostname
# and: https://doc.traefik.io/traefik/getting-started/faq/#what-are-the-forwarded-headers-when-proxying-http-requests
KC_HOSTNAME: FQDN
KC_PROXY_HEADERS: xforwarded
KC_DB: postgres
KC_DB_URL_HOST: postgresql-service
KC_DB_URL_PORT: "5432"
# We need to enable http, as we are behind an ingress
KC_HTTP_ENABLED: "true"
# TODO Maybe also enable load shedding
# KC_HTTP_MAX_QUEUED_REQUESTS: 2000

View file

@ -15,10 +15,9 @@ spec:
labels:
app: keycloak
spec:
# TODO: Add Resource allocations
containers:
- name: keycloak
image: quay.io/keycloak/keycloak:25.0.4
image: quay.io/keycloak/keycloak:20.0.3
imagePullPolicy: IfNotPresent
args:
- start
@ -26,13 +25,48 @@ spec:
- name: keycloak-cert
mountPath: /etc/certs
readOnly: true
envFrom:
- configMapRef:
name: keycloak-env
- secretRef:
env:
- name: KC_HTTPS_CERTIFICATE_FILE
value: /etc/certs/tls.crt
- name: KC_HTTPS_CERTIFICATE_KEY_FILE
value: /etc/certs/tls.key
- name: KC_HOSTNAME
value: FQDN
- name: KC_PROXY
value: edge
- name: DB_VENDOR
value: POSTGRES
- name: DB_ADDR
value: postgresql-service
- 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
valueFrom:
secretKeyRef:
name: postgres-secret
key: postgres-password
- name: KEYCLOAK_ADMIN
valueFrom:
secretKeyRef:
name: keycloak-secret
key: keycloak-user
- name: KEYCLOAK_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: keycloak-secret
key: keycloak-password
ports:
- name: keycloak
- name: http
containerPort: 8080
volumes:
- name: keycloak-cert

View file

@ -5,7 +5,5 @@ metadata:
namespace: NAMESPACE
type: Opaque
data:
KC_DB_USERNAME: DBUSER
KC_DB_PASSWORD: DBPW
KEYCLOAK_ADMIN: ADMIN_USER
KEYCLOAK_ADMIN_PASSWORD: ADMIN_PASS
keycloak-user: admin
keycloak-password: admin

View file

@ -13,30 +13,66 @@
:metadata {:name "keycloak-secret", :namespace "keycloak"}
:type "Opaque"
:data
{:KC_DB_USERNAME "a2V5Y2xvYWs="
:KC_DB_PASSWORD "ZGItcGFzc3dvcmQ="
:KEYCLOAK_ADMIN "dXNlcg=="
:KEYCLOAK_ADMIN_PASSWORD "cGFzc3dvcmQ="}}
(cut/generate-secret {:namespace "keycloak" :fqdn "test.de"}
{:keycloak-admin-user "user" :keycloak-admin-password "password"
:postgres-db-user "keycloak"
:postgres-db-password "db-password"}))))
(deftest should-generate-configmap
(is (= {:apiVersion "v1",
:kind "ConfigMap",
:metadata {:name "keycloak-env", :namespace "keycloak"},
:data
{:KC_HTTPS_CERTIFICATE_FILE "/etc/certs/tls.crt",
:KC_HTTPS_CERTIFICATE_KEY_FILE "/etc/certs/tls.key",
:KC_HOSTNAME "test.de" ,
:KC_PROXY_HEADERS "xforwarded" ,
:KC_DB "postgres",
:KC_DB_URL_HOST "postgresql-service",
:KC_DB_URL_PORT "5432",
:KC_HTTP_ENABLED "true"}}
(cut/generate-configmap {:namespace "keycloak" :fqdn "test.de"}))))
{:keycloak-user "dXNlcg=="
:keycloak-password "cGFzc3dvcmQ="}}
(cut/generate-secret {:namespace "keycloak" :fqdn "test.de"} {:keycloak-admin-user "user" :keycloak-admin-password "password"}))))
(deftest should-generate-deployment
(is (= {:name "keycloak", :namespace "keycloak", :labels {:app "keycloak"}}
(:metadata (cut/generate-deployment {:fqdn "example.com" :namespace "keycloak"})))))
(is (= {:apiVersion "apps/v1",
:kind "Deployment",
:metadata
{:name "keycloak", :namespace "keycloak", :labels {:app "keycloak"}},
:spec
{:replicas 1,
:selector {:matchLabels {:app "keycloak"}},
:template
{:metadata {:labels {:app "keycloak"}},
:spec
{:containers
[{:name "keycloak",
:image "quay.io/keycloak/keycloak:20.0.3",
:imagePullPolicy "IfNotPresent",
:args ["start"],
:volumeMounts
[{:name "keycloak-cert",
:mountPath "/etc/certs",
:readOnly true}],
:env
[{:name "KC_HTTPS_CERTIFICATE_FILE",
:value "/etc/certs/tls.crt"}
{:name "KC_HTTPS_CERTIFICATE_KEY_FILE",
:value "/etc/certs/tls.key"}
{:name "KC_HOSTNAME", :value "test.de"}
{:name "KC_PROXY", :value "edge"}
{:name "DB_VENDOR", :value "POSTGRES"}
{:name "DB_ADDR", :value "postgresql-service"}
{: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",
:valueFrom
{:secretKeyRef
{:name "postgres-secret", :key "postgres-password"}}}
{:name "KEYCLOAK_ADMIN",
:valueFrom
{:secretKeyRef
{:name "keycloak-secret", :key "keycloak-user"}}}
{:name "KEYCLOAK_ADMIN_PASSWORD",
:valueFrom
{:secretKeyRef
{:name "keycloak-secret", :key "keycloak-password"}}}],
:ports [{:name "http", :containerPort 8080}]}],
:volumes
[{:name "keycloak-cert",
:secret
{:secretName "keycloak",
:items
[{:key "tls.crt", :path "tls.crt"}
{:key "tls.key", :path "tls.key"}]}}]}}}}
(cut/generate-deployment {:fqdn "test.de" :namespace "keycloak"}))))